【题目】

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

【分析】

这是一道很新颖的关于位运算的面试题。

X^X = 0, X^0 =X。

首先我们考虑这个问题的一个简单版本:一个数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。

这个题目的突破口在哪里?题目为什么要强调有一个数字出现一次,其他的出现两次?我们想到了异或运算的性质:任何一个数字异或它自己都等于0。也就是说,如果我们从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现1次的数字,因为那些出现两次的数字全部在异或中抵消掉了。

有了上面简单问题的解决方案之后,我们回到原始的问题。如果能够把原数组分为两个子数组。在每个子数组中,包含一个只出现一次的数字,而其他数字都出现两次。如果能够这样拆分原数组,按照前面的办法就是分别求出这两个只出现一次的数字了。

我们还是从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。由于这两个数字肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。我们在结果数字中找到第一个为1的位的位置,记为第N位。现在我们以第N位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0。

现在我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。因此到此为止,所有的问题我们都已经解决。

【代码】

 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
 
unsigned int FindFirstBitIs1(int number)
{
    // 110 --->n=1 (start from 0)
;
    )
    {
        n++;
    }
    return n;
}

bool IsBit1(int number, unsigned int indexBit)
{
    // 110,2---> true; 100,2--->false
 << indexBit;
    return number & temp;
}

void FindNumbersAppearOnce(int data[], int length, int &num1, int &num2)
{
    )
        return;

// get the exclusive or result of array
;
    ; i < length; ++i)
    {
        resultExclusiveOR ^= data[i];
    }

// find the index of first bit 1 in resultExclusiveOR
    int indexBit = FindFirstBitIs1(resultExclusiveOR);
    num1 = num2 = ;
    ; j < length; ++j)
    {
        // divide numbers in data into 2 groups:
        // numbers in group1: the indexBit number is 1
        // numbers in group2: the indexBit number is 0
        if (IsBit1(data[j], indexBit))
        {
            num1 ^= data[j];
        }
        else
        {
            num2 ^= data[j];
        }
    }
}

参考】

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

34.数组中2个只出现一次的数字[Find two numbers which appear once]的更多相关文章

  1. 59. 总结篇:数组中N(n=1,2,3)个只出现一次的数字[find N numbers which appear only once in array]

    [本文链接] http://www.cnblogs.com/hellogiser/p/find-n-numbers-which-appear-only-once-in-array.html [题目] ...

  2. 给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)

    """ #给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 #返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况) 解题思路: 1.设定一个 ...

  3. 获取数组中多个相加等于0的一组数字 javascript

    //获取数组中两个相加等于0的一对数字,比如[ [ -10, 10 ], [ -5, 5 ] ] var arr=[-5,10,1,-10,3,4,5,9] //对数组进行排序 arr.sort(fu ...

  4. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  5. [LeetCode] 421. Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  6. C++求解数组中出现超1/4的三个数字。

    #include <iostream> using namespace std; //求x!中k因数的个数. int Grial(int x,int k) { int Ret = 0; w ...

  7. 剑指Offer39 数组中寻找和为sum的两个数字

    /************************************************************************* > File Name: 39_TwoNum ...

  8. 输出数组中出现次数最多且值最大的数字----python

    class Solution(): #求最多的数 def find_max(self,list): num = 0 for i in list: print(i) if list.count(i) & ...

  9. 剑指Offer 40. 数组中只出现一次的数字 (数组)

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 题目地址 https://www.nowcoder.com/practice/e02fdb54 ...

随机推荐

  1. poj 3070 矩阵快速幂模板

    题意:求fibonacci数列第n项 #include "iostream" #include "vector" #include "cstring& ...

  2. Linux Network IO Model、Socket IO Model - select、poll、epoll

    目录 . 引言 . IO机制简介 . 阻塞式IO模型(blocking IO model) . 非阻塞式IO模型(noblocking IO model) . IO复用式IO模型(IO multipl ...

  3. 无线安全: 通过伪AP进行DHCP+DNS劫持的钓鱼攻击

    有了之前学习802.11的数据帧格式.芯片硬件参数学习的基础后,我们接下来继续学习无线安全中黑客是怎样进行流量劫持攻击的 相关学习资料 http://www.freebuf.com/articles/ ...

  4. C#图片读取和保存

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. MyEclipse使用SVN进行项目版本控制

    一.搭建SVN服务器. 例如,使用VisualSVN Server,下载后安装. (1)在Repositories(版本库)上右击,新建Repository,选择Regular FSFS reposi ...

  6. java中request,application,session三个域及参数简单示例

    直接上代码: java代码: public class HelloAction implements Action { @Override public String execute() throws ...

  7. 深入分析Java Web中的中文编码问题

    要对Java Web项目进行编码原因: 1.在计算机中存储信息的最小单位是1个字节,即8个bit,所以能表示的字符范围是0~255个. 2.电脑需要表示的符号太多.无法用1个字节完全表示. 要解决这个 ...

  8. map vs hash_map

    1. map, multimap, set, multiset g++ 中 map, multimap, set, multiset 由红黑树实现 map: bits/stl_map.h multim ...

  9. C# 反射创建对象,包括创建引用外部程序集类的实例

    #region 根据对象名成创建对象 /// <summary> /// 根据对象名成创建对象 /// </summary> /// <param name=" ...

  10. c# 重写索引

    //using System;//using System.Collections.Generic;//using System.Text; //namespace 索引//{//    class ...