【01】数组中只出现一次的数字

其他两次,一个一次/其他三次,一个一次/其他两次,两个一次

============================================

任何一个数字异或他自己都得零。

注意异或运算的初始化变量为0,因为0异或任何数字都得那个数字自身。

Single Number

1.一个整型数组中除了一个数字之外,其他数字都出现了两次 ,找出这个出现一次的数字。

解法一,异或是重复的消失,剩下的就是要找的数字。

C++
Code






1
2
3
4
5
6
7
8
9
10
11
12
13

 

int singleNumber(int A[], int n)
{
    if(n < 0)
    {
        return -1;
    }
    int result = 0;
    for(int i = 0; i < n; ++i)
    {
        result ^= A[i];/*1^1=0 0^0=0*/
    }
    return result;
}

Single Number II

2.一个整型数组中除了一个数字之外,其他数字都出现了三次 ,找出这个出现一次的数字。

解法一,用一个数组模拟三进制运算,但是耗费空间复杂度,超过3,就对3取模。

C++
Code






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

 

int singleNumber(int A[], int n)
{
    //一个整数的bit数,即整数字长
    const int W = sizeof(int) * 8;
    //表示在i位出现的1的个数
    int count[W];
    //注意这里乘以4不要忘记了
    memset(count, 0, W * 4);
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < W; ++j)
        {
            count[j] += (A[i] >> j) & 0x1;
            if(count[j] >= 3)
            {
                /*因为每次累加1*/
                count[j] = 0;
            }
        }
    }
    int result = 0;
    for(int i = 0; i < W; ++i)
    {
        result += (count[i] << i);
    }
    return result;
}

解法二,用位运算记录出现一次的,出现两次的,出现三次的,

然后每次迭代,把出现三次的从出现两次的和出现一次的当中去除。















异或

1 & 1 = 1

1 & 0 = 0

0 & 1 = 0

0 & 0 = 0

1 | 1 = 1

1 | 0 = 1

0 | 1 = 1

0 | 0 = 0

~1 = 0

~0 = 1

1 ^ 1 = 0

1 ^ 0 = 1

0 ^ 1 = 1

0 ^ 0 =
0

C++
Code






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

 

int singleNumber(int A[], int n)
{
    int ones = 0, twos = 0, threes = 0;
    for(int i = 0; i < n; i++)
    {
        //已经出现两次并且再次出现
        threes = twos & A[i];
        //曾经出现两次的或者曾经出现一次但是再次出现的
        twos = twos | (ones & A[i]);
        //出现一次的
        ones = ones | A[i];

        //当某一位出现三次后,我们就从出现两次中消除该位
        twos = twos & ~threes;
        //当某一位出现三次后,我们就从出现一次中消除该位
        ones = ones & ~threes;
    }
    //twos, threes最终都为0.ones是只出现一次的数
    return ones;
}

面试题40:数组中只出现一次的数字

3.一个整型数组中除了两个数字之外,其他数字都出现了两次,找出这两个只出现一次的数字。

根据问题1,从头到尾以后得到的是这两个出现一次的数字的异或的结果。这个异或的结果肯定不为0。

不为0,也就是说结果数字的二进制表示中至少就有一位为1。

我们从右到左找到这个第一个不为0的位置,然后利用这一位是不是0把这个数组分成两个子数组,

这两个子数组,中各包含一个只出现一次的数字,

为什么呢,因为,如果a^b的结果,某一位为1说明,a和b的这个位置是不同的!!!

而且如果这一位如果相同,那么它们可能是重复的数字,我们就把他们分配到同一个数组中!!!

C++
Code






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

 

#include <iostream>
using namespace std;

bool IsBit1(int num, unsigned int indexBit)
{
    num = num >> indexBit;
    return (num & 1);
}

unsigned int FindFirstBitIs1(int num)
{
    int indexBit = 0;
    while ( ((num & 1) == 0) && (indexBit < 8 * sizeof(int)) )
    {
        num = num >> 1;
        ++ indexBit;
    }
    return indexBit;
}

void FindNumsAppearOnce(int data[], int length, int *num1, int *num2)
{
    if (data == NULL || length < 2)
    {
        return ;
    }
    int resultExclusiveOR = 0;
    for (int i = 0; i < length; ++i)
    {
        resultExclusiveOR ^= data[i];
    }

    unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);

    *num1 = *num2 = 0;
    for (int j = 0; j < length; ++j)
    {
        if (IsBit1(data[j], indexOf1))
        {
            *num1 ^= data[j];
        }
        else
        {
            *num2 ^= data[j];
        }
    }
}

int main()
{
    int data[] = {2, 4, 3, 6, 3, 2, 5, 5};
    int length = sizeof(data) / sizeof(data[0]);
    int num1, num2;
    FindNumsAppearOnce(data, length, &num1, &num2);
    cout << num1 << " " << num2 << endl;
    return 0;
}

【01】数组中只出现一次的数字,布布扣,bubuko.com

时间: 2024-08-04 19:51:14

【01】数组中只出现一次的数字的相关文章

数组中只出现一次的数字(剑指offer)思维有点巧

数组中只出现一次的数字 参与人数:1144时间限制:1秒空间限制:32768K 通过比例:21.75% 最佳记录:0 ms|0K(来自  牛客563536号) 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 题目链接:http://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?rp=2&ru=/ta/coding-interviews&qru=/ta/coding

数组中只出现一次的数字-剑指Offer

数组中只出现一次的数字 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 先考虑一个数组里只有一个数出现一次,其他两个数都出现两次的情况:一个数跟自己异或后为0,一个数组里只有一个数出现一次其他两次,挨个异或后最后得到的结果就是只出现一次的那个数. 我们把这个数组分为两部分,每部分只有一个数只出现一次:我们分的时候,把所有数都异或后,得到的结果肯定不为0,其实是那两个只出现一次的不同的数的异或,我们从低位到高危找到第一个不为0的那位,异

编程算法 - 数组中只出现一次的数字 代码(C)

数组中只出现一次的数字 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 一个整型数组里除了两个数字以外, 其他的数字都出现了两次. 请写程序找出这两个只出现一次的数字. 如果从头到尾依次异或数组中的每一个数字, 那么最终的结果刚好是那个只出现一次的数字. 根据结果数组二进制某一位为1, 以此分组, 为1的一组, 为0的一组, 再重新进行异或. 最后得出两个结果. 时间复杂度O(n). 代码: /* * main.cpp * * Create

剑指offer系列源码-数组中只出现一次的数字

题目1351:数组中只出现一次的数字 时间限制:1 秒内存限制:32 兆特殊判题:否提交:2582解决:758 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3 2 5 5

【剑指offer】数组中只出现一次的数字(1)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3

[剑指Offer]40.数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 我们直到异或的性质: 任何一个数字异或他自己都等于0. 所以说我们如果从头到尾依次异或每一个数字,那么最终的结果刚好只出现一次的数字,因为成对出现的两次的数字全部在异或中抵消了. 这道题中有两个数字只出现一次.这样的话我们得到的结果就是这两个数字的异或结果.因此我们想办法把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字.这样我们就可以对这两个子数组分别异或,就能得到两个只出现一

【4】数组中只出现一次的数字

题目:输入一个整型数组,数组里除了两个数出现一次之外,其它所有数字出现的次数都是2次,求这两个数字.要求时间复杂度为O(n),空间复杂度为O(1) 1 题目要求时间复杂度为O(n)并且空间复杂度为O(1).这个时候朴素的方法利用数字来记录出现次数的方案都是不行的. 2 根据题目的特点,只有两个数出现一次,其它的所有数据都是出现2次.如果这两个数是a和b,那么对这个数组异或的结果就是a^b.现在我们就是要考虑怎么把数组分成两部分,一部分含有a,一部分含有b,则每部分异或的结果即为两个数a和b的值

九度OJ 1351 数组中只出现一次的数字 (位操作)

题目1351:数组中只出现一次的数字 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2597 解决:766 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3 2

34.数组中只出现一次的数字

http://zhedahht.blog.163.com/blog/static/2541117420071128950682/ http://blog.csdn.net/maoxunxing/article/details/11386407 http://zhedahht.blog.163.com/blog/static/25411174201283084246412/ http://blog.csdn.net/wuzhekai1985/article/details/6704794 题目:一