【题 目】一个整型数组中除了两个数字外,其他的数字都出现两次。请找出这两个只在数组中出现一次的数字。要求时间复杂度O(n),空间复杂度O(1)。

【思 路】首先我们考虑一个稍微简单点的情况:如果这个数组中只有一个数字出现且仅出现一次,其他数字都出现两次,我们应该怎么样找出这个数字呢?我们题目说数字出现两次有什么深意呢?我们很容易联想到异或运算,因为任何一个数字和自身异或的结果为0;知道了这点,我们就很容易知道,我们将所有的数字进行异或,其结果就是仅出现一次的数字,因为其他所有的数字都两两异或为0了。

  有了上面那个简单题目作为引子,我们很容易想到,如果我们将原题目的数组成功的分为两个子数组,而每个子数组恰好含有一个仅出现一次的数字,那么我们就可以根据上面的思路直接求解。怎么划分这两个子数组呢?

  我们仍然将原数组中的所有数字进行异或运算,容易知道,异或的结果实际上就是两个仅出现一次的数字的异或结果,因为这两个数字不相等,所以异或的结果肯定不为0,我们可以找到异或结果中,第一个为1的位,这说明在该位上,必然有一个数字为1,另一个数字在该为上为0;我们可以按照这个结果,对所有该位上为1的数字分为一组,而将该位上为0的位分为另一组,这样我们就成功的讲原问题转换为两个简单的子问题。再对子问题全部异或,即可获得两个仅出现一次的数字。按照这个思路,我们可以得到如下的代码:

 1 #include<iostream> 2 #include<string> 3 using namespace std; 4  5 //判断一个数number的第bitIndex位是否为1 6 bool IsBit1(int number,unsigned int bitIndex) 7 { 8     number = number>>bitIndex; 9     return (number & 1);10 }11 12 //找到num中第一个位是1的位13 unsigned int FindFirstbitOf1(int num)14 {15     int bitIndex = 0;16     while(bitIndex < 32 && ((num & 1) == 0))17     {18         num = num>>1;19         bitIndex++;20     }21 22     //该函数的另一种循环结构,完全等价23 /*    for(bitIndex = 0;bitIndex < 32;++bitIndex,num = num>>1)24     {25         if((num & 1) ==1)26             break;27     }28 */29     return bitIndex;30 }31 32 void FindNumbersAppearOnce(int data[],unsigned int length,int &num1,int &num2)33 {34     //无效输入35     if(data == NULL || length < 2)36         return;37 38     //得到num1异或num239     int resultOfBitOR = 0;40     for(int i = 0;i < length;++i)41     {42         resultOfBitOR ^= data[i];43     }44 45     //找到num1^num2的结果中第一个为1的位46     unsigned int index = FindFirstbitOf1(resultOfBitOR);47 48     num1 = 0;49     num2 = 0;50 51     //将index位的取值是否为1分为两组52 //将每一组的全部数字做异或53     for(int j= 0;j < length;++j)54     {55         if(IsBit1(data[j],index))56             num1 ^= data[j];57         else58             num2 ^= data[j];59     }60 61 62 }63 64 int main()65 {66     cout<<"Please Enter your ArrayLength:"<<endl;67     int arraylength = 0;68     cin>>arraylength;69 70     int *array = new int[arraylength];71     cout<<"Please Enter the numbers in your Array:"<<endl;72     for(int k = 0;k < arraylength;++k)73     {74         cin>>array[k];75     }76 77     int result1 = 0;78     int result2 = 0;79     FindNumbersAppearOnce(array,arraylength,result1,result2);80 81     cout<<"the numbers appear once in your array are:"<<endl;82     cout<<result1<<"\t"<<result2<<endl;83 84     return 0;85 }

  测试及运行结果如下:


References:

何海涛博客:http://zhedahht.blog.163.com/blog/static/2541117420071128950682/

注:

1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。

2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。

转载于:https://www.cnblogs.com/python27/archive/2011/12/07/2279980.html

【算法14】找出数组中两个只出现一次的数字相关推荐

  1. 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)

    1.8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下 ...

  2. 找出数组中两个只出现一次的数字

    题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字 通过这道题感觉位运算很强大~这道题利用异或的几个性质:任何数与其本身异或值都为0,异或运算满足交换律. ...

  3. 找出数组中两个只出现了一次的数

    原题:给一组数,只有两个数只出现了一次,其他所有数都是成对出现的.怎么找出这两个数. 编写函数实现. 对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,经过 ...

  4. 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。

    笔者初涉<算法设计与分析>这门专业课,在做一些算法设计题的过程中遇到一些小感悟,特此记录和大家分享. 下面直接给出算法题目: 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高 ...

  5. 找出数组中第k大和第m大的数字之和

    找出数组中第k大和第m大的数字之和 说明:定义一个函数,接受三个参数getMaxNumber(array,k,m){},找出第k大和第m大的数字之和.重复的数组也需要计算 比如:[1,3,4,5,4, ...

  6. 算法题:找出整数数组中两个只出现一次的数字

    问题:一个整数数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度为O(n),空间复杂度为O(1). 分析:这是一个很新颖的关于位运算的题目. 首先考虑这 ...

  7. 【408计算机考研】|【2018统考真题-41】| 给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数

    目录 一.题目 二.解答 三.测试数据 一.题目   给定一个含 n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算 法,找出数组中未出现的最小正整数.例如,数组{-5, 3, 2, 3}中未 ...

  8. java 算法之找出数组中第二大的数

    1.如果仅考虑实现功能而不考虑效率,可以先通过排序算法将数组排序,然后根据数组下标来访问数组中第二大的数,,最快的排序算法一般为快速排序算法,但是其时间复杂度为(nlogn),根据下标访问需要便利一遍 ...

  9. 巧妙算法:找出数组中消息的数字

    题目: 在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如,如果输入长度为7, ...

最新文章

  1. Mysql 查看连接数,状态 最大并发数 怎么设置才合理
  2. chrome表单自动填充去掉input黄色背景
  3. 物联网发展年报显示 2016年智能家居市场快速增长
  4. Vue axios发送Http请求
  5. strncpy 用法
  6. 这位 50 岁的海归程序员,当着老板还在天天改 Bug
  7. linux 系统基础知识 - vgextend命令
  8. 券商交易模式下的单产品多券商方案
  9. 换硬币-零钱换成5分、2分和1分的硬币
  10. 无人机倾斜摄影测绘工程毕业论文范文
  11. 图数据库查询语言Cypher
  12. Terraria(泰拉瑞亚)存档覆盖(Linux)
  13. 分布式监控:zabbix trapper方式监控
  14. 【stm32f0】stm32 总中断的打开与关闭
  15. java线程池的参数设置
  16. 力扣18. 四数之和
  17. 宝宝头上有一圈不长头发
  18. JavaScript函数的使用以及下拉框、文本框、radio值的获取,结合一个淘宝竞价案例。。。
  19. Android取消EditText自动默认获取焦点行为
  20. 京东快报轮播公告的实现

热门文章

  1. each 数据获取attr_Python数据分析 — 基于RFM的精细化用户分层
  2. java asynctask完成_如何传递参数并从AsyncTask类中获取结果?
  3. linux 文件系统 dfs,分布式文件系统fastDFS 机器硬件要求
  4. spring的sanpshot报错_最详细的 Spring Boot 多模块开发与排坑指南
  5. Linux删除安卓温控,RK平台关闭温度控制降频功能
  6. matlab 解非齐次方程组,各位看一下为什么这里的LU解不出非齐次线性方程组?
  7. flash推荐助手怎么关掉_彻底清除“FF新推荐”“Flash助手”的弹出广告
  8. ubuntu cmake安装_如何在Emacs中得到一个真正的Terminal?vterm安装指南
  9. word无法验证服务器,windows10系统下office2010无法验证的解决方法
  10. 计算机winform参考文献写,毕业论文基于C#WinForm的语音通信系统设计.doc