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

分析:由于题目要求时间复杂度为O(n),所以先排序然后比较相邻数字是否相同的思路被排除。

空间复杂度是O(1),辅助空间被限制,所以hash表的思路也被排除。

那么这个题的突破口在哪里呢?注意这个数组的特殊性:其它数字都出现了两次,只有一个数出现了一次。可以想到运用异或运算,任何一个数字异或它自己都等于0。

如果我们从头到尾依次异或数组中的每一个数,那么最终的结果就是那个只出现一次的数字,因为其他出现两次的数字全部在异或中被抵消为0了(异或运算遵循交换分配率)。

举个栗子:2  3  4  2  3

所有数字依次异或运算:2 xor 3 xor 4 xor 2 xor 3 = (2 xor 2) xor (3 xor 3) xor 4= 0 xor 0 xor 4 = 4

最终结果4就是我们要找的那个只出现一次的数字。

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

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

分析:数组里包含了两个只出现一次的数字,那么所有数字依次异或的结果就是这两个只出现一次的数字的异或结果。我们要想办法利用这个异或结果,把数组分为两个子数组,一个子数组包含一个只出现一次的数字,另一个数组包含另一个只出现一次的数字。由于这两个只出现一次的数字肯定不相等,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。我们在结果数字中找到第一个为1的位的位置,记为第N位。现在我们以第N位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0。

举个栗子:1 2 3 4 2 3

所有数字异或结果 = 1 xor 4

二进制表示为:  001

xor 100

_______

101

异或结果的二进制位101,第一个为1的位的位置N=1。

那么,数组所有数的二进制表示中,第N(N=1)位为1的的数为1 3 3,第N(N=1)位为0的的数为2 2 4.

这样就把原数组拆分为两个子数组,1和4被分到不同的数组中去了。然后分别在两个子数组中找只出现一次的那个数。

void FindNumsAppearOnce(int data[], int length, int &num1, int &num2)
{if (length < 2)return;// get num1 ^ num2int resultExclusiveOR = 0;for (int i = 0; i < length; ++ i)resultExclusiveOR ^= data[i];// get index of the first bit, which is 1 in resultExclusiveORunsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);  num1 = num2 = 0;for (int j = 0; j < length; ++ j){// divide the numbers in data into two groups,// the indexOf1 bit of numbers in the first group is 1,// while in the second group is 0if(IsBit1(data[j], indexOf1))num1 ^= data[j];elsenum2 ^= data[j];}
}// Find the index of first bit which is 1 in num (assuming not 0)
unsigned int FindFirstBitIs1(int num)
{int indexBit = 0;while (((num & 1) == 0) && (indexBit < 32)){num = num >> 1;++ indexBit;}return indexBit;
}// Is the indexBit bit of num 1?
bool IsBit1(int num, unsigned int indexBit)
{num = num >> indexBit;return (num & 1);
}

经典算法题1:找出数组中只出现一次的数字,其它数字都出现了两次相关推荐

  1. 小小c#算法题 - 1 - 找出数组中满足条件的两个数

    把一些东西放到网上,看的时候方便一些.代码可能有bug且不是最佳解决方案,仅供参考. 题目:输入一个按升序排序的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字. 要求时间复杂度是 ...

  2. 找出数组中只出现了一次的数字(Java)

    找出数组中只出现了一次的数字 题目 题目分析 方法1 方法2 方法3 代码实现 主方法 方法1 第一种:使用计数器的 第二种:不使用计数器 方法2 方法3 总结 题目 给定一个非空整数数组,除了某个元 ...

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

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

  4. 找出数组中只出现一次的数

    case1 一个整形数组中除了一个数字之外,其他数字都出现了两次,请找出这个数.要求时间复杂度O(n),空间复杂度O(1). 思路: 关键词:一次,两次. 出现两次会带来什么效果?联想到异或,一个数与 ...

  5. 【算法14】找出数组中两个只出现一次的数字

    [题 目]一个整型数组中除了两个数字外,其他的数字都出现两次.请找出这两个只在数组中出现一次的数字.要求时间复杂度O(n),空间复杂度O(1). [思 路]首先我们考虑一个稍微简单点的情况:如果这个数 ...

  6. 找出数组中只出现过一次的数

    一个大数组,在1到25000之间,只有4K memory, 打印出其中正好只出现过一次的数.没出现过,出现过2次,3次,或更多,都不打印. solutions: 1)位图法,但每个数有3个状态:0,1 ...

  7. 找出数组中只出现1次的两个元素

    通过位运算可以得到只出现1次的唯一元素,但是如果有两个元素出现1次,则需要更进一步. 对整个数组依次进行异或运算后,得到的是两个出现一次元素的异或,之后将这两个元素的最后面是1的位记录下来,并以此为标 ...

  8. 数据结构 2018统考题【找出数组中未出现的最小正整数】

    王道论坛课本

  9. 《编程题》找出数组中出现次数超过一半的数(时间复杂度O(n),空间复杂度为O(1))

    解析:该题目可以用mapreduce的wordcount思想做,就是存储键.值对,键存数字,值存该数字出现的次数,当然需要用一个变量记住出现次数超过一半的数了,说完了,开始撸起袖子干了. public ...

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

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

最新文章

  1. stm32.cube介绍
  2. css多行超出显示点_CSS实现单行、多行文本溢出显示省略号(…)
  3. 计算机二级一年几次湖南省,湖南省计算机二级多少分可以通过
  4. exe4j生成可执行程序的使用方法
  5. 移动数据平台mParticle获1750万美元B轮融资,帮助企业快速获取客户数据
  6. 将js进行到底:node学习10
  7. Nacos配置文件覆盖问题
  8. c语言编程车,C语言编程之自动类型转化
  9. java 批次号生成_批次号生成
  10. Chrome插件安装 程序包无效
  11. 推荐几个微信小程序开源项目
  12. 贝叶斯网络python实现_在Python中使用贝叶斯网络的实例
  13. 简单几步开启Mac访问NTFS格式读写
  14. 带蓝色的紫罗兰色——五色配色篇
  15. YYC松鼠聚合直播系统添加图片上传视频提示网络错误的问题解决方案
  16. 基于bert的platos republic i ii情绪分析和可视化
  17. html中qq号码怎么写,qq号码免费申请6位号的方法
  18. java将数据写入excel_java将数据写入excel
  19. Vue-GoogleMap (一)实时定位
  20. 不一样的SpringBoot注解

热门文章

  1. 大数据平台及挖掘调研
  2. 浏览器的标签栏上网站的小图标的设置方式
  3. sqlite 多条件查询
  4. oracle odi 资料档案库访问期间出现未分类的异常错误,ODI11g调用DBLink时报ORA-28267: Invalid NameSpace Value错误...
  5. ajax批量上传数据,Ajax上传数据和上传文件(三种方式)
  6. 【电脑运用及修理】6套台式组装机电脑配置清单大全(2022年618)
  7. 简述台式计算机的组装流程,台式机怎么组装 台式机组装步骤详细介绍【图文】...
  8. com.mysql.jdbc.Connection.isValid(I)Z错误解决办法
  9. ARM DS5 项目build后无法找到axf文件
  10. java生成exe_java生成可执行文件的方法总结