题目:

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路:

这道题的简单版本是除了一个数字之外,其他数字都出现了两次,这个很简单,将所有的数异或一遍就得到了那个数字。

如果不考虑空间复杂度的话,通过hash表统计的方法可以得到这两个数字;但如果空间复杂度要求为O(1),还是得参考异或的方法。

很明显,如果将数组中所有的数都异或一遍,那么得到结果就是剩下两个数字的异或结果,因为这是两个不同的数字,因此异或结果不可能为0。

那么这个结果的二进制表示中肯定存在某个二进制位为1,其中一个数在该位为0,另一个数在该位为1。

通过该位,我们可以将数组分成两类,一类在该位为0,一类在该位为1,将这两类数各自异或就可以得到两个只出现一次的数字。

代码:

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. unsigned int FindFirstBitIs1(int num){
  6. int indexBit=0;
  7. unsigned int count=1;
  8. while((num&count)==0){
  9. count=count<<1;
  10. indexBit++;
  11. }
  12. return indexBit;
  13. }
  14.  
  15. bool IsBit1(int num,unsigned int indexBit){
  16. num=num>>indexBit;
  17. return (num&1);
  18. }
  19.  
  20. void FindNumsAppearOnce(int data[],int length,int& num1,int &num2){
  21. if(data==NULL || length<=1)
  22. return;
  23.  
  24. int resultExclusiveOR=0;
  25. for(int i=0;i<length;i++){
  26. resultExclusiveOR^=data[i];
  27. }
  28.  
  29. unsigned int indexOf1=FindFirstBitIs1(resultExclusiveOR);
  30.  
  31. num1=0;
  32. num2=0;
  33. for(int i=0;i<length;i++){
  34. if(IsBit1(data[i],indexOf1))
  35. num1^=data[i];
  36. else
  37. num2^=data[i];
  38. }
  39. }
  40.  
  41. int main()
  42. {
  43. int A[]={1,2,4,2,1,5,6,7,6,7};
  44. int len=sizeof(A)/sizeof(A[0]);
  45. int num1=0;
  46. int num2=0;
  47. FindNumsAppearOnce(A,len,num1,num2);
  48. cout << num1 << " " << num2 << endl;
  49. return 0;
  50. }

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/e02fdb54d7524710a7d664d082bb7811?rp=2

AC代码:

  1. class Solution {
  2. public:
  3. bool IsBitOf1(int num,int k){
  4. num=num>>k;
  5. return (num&1);
  6. }
  7.  
  8. int findFirstBitOf1(int num){
  9. int indexOf1=0;
  10. int count=1;
  11. while((num&count)==0){
  12. count=count<<1;
  13. indexOf1++;
  14. }
  15. return indexOf1;
  16. }
  17.  
  18. void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
  19. int length=data.size();
  20. if(length<=1)
  21. return;
  22.  
  23. int result=0;
  24. for(int i=0;i<length;i++)
  25. result^=data[i];
  26.  
  27. int indexOf1=findFirstBitOf1(result);
  28.  
  29. *num1=0;
  30. *num2=0;
  31. for(int i=0;i<length;i++){
  32. if(IsBitOf1(data[i],indexOf1))
  33. *num1^=data[i];
  34. else
  35. *num2^=data[i];
  36. }
  37. }
  38. };

  

(剑指Offer)面试题40:数组中只出现一次的数字的更多相关文章

  1. 剑指Offer - 九度1351 - 数组中只出现一次的数字

    剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...

  2. 剑指offer四十之数组中只出现一次的数字

    一.题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 二.思路 建一个hashMap,统计各数字出现的次数,然后遍历hashMap,输出出现一次的数字 ...

  3. 剑指offer 面试题56. 数组中只出现一次的两个数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...

  4. 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)

    PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...

  5. 剑指Offer - 九度1348 - 数组中的逆序对

    剑指Offer - 九度1348 - 数组中的逆序对2014-01-30 23:19 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个 ...

  6. 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字

    剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...

  7. 剑指offer:二维数组中的查找

    目录 题目 解题思路 具体代码 题目 题目链接 剑指offer:二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺 ...

  8. 剑指 Offer 04. 二维数组中的查找 (思维)

    剑指 Offer 04. 二维数组中的查找 题目链接 本题的解法是从矩阵的右上角开始寻找目标值. 根据矩阵的元素分布特性, 当目标值大于当前位置的值时将row行号++,因为此时目标值一定位于当前行的下 ...

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

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

  10. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

随机推荐

  1. python配置libsvm

    转载博文:win10(64-bit) + python3.6.0(64-bit) 配置libsvm-3.22 https://blog.csdn.net/weixin_35884839/article ...

  2. AM335x开发板与PC机虚拟机建立tftp文件传输

    1.AM335x开发板必须要支持以太网,而且在U-boot中要有完好的以太网驱动 因为开发板的储存介质为SD卡,所以在编译好的U-boot中并没有配置网络环境,为了不使每次上电都修改u-boot的网络 ...

  3. struts2和1的区别

    先大致介绍下struts1和struts2 struts:过去最流行的web MVC组件,apache项目组的一个开源项目. struts2:现在非常流行的web MVC组件,是apache用stru ...

  4. zabbix-python api(一)

    获取zabbix token #!/usr/bin/env python #coding=utf-8 import json import urllib2 def Gettoken(server_ip ...

  5. MySQL笔记(二)之数据检索常用关键字

    SELECT 用于数据的选择 语法: SELECT 列 FROM 表; #从表中选择某些列,也可以是*,代表全部列 DISTINCT 当某些列包含重复值的时候,DISTINCT用于过滤掉重复值,使重复 ...

  6. 51nod1218 最长递增子序列 V2

    看见标签推荐顺便就做了吧 记$f[i], g[i]$为$i$的含$i$的前缀最长递增子序列和后缀递增子序列 只要满足$f[i] + g[i] == LIS + 1$,那么$i$就是可能的 对于$i$而 ...

  7. 1.8(SQL学习笔记)触发器

    一.触发器简介 当需要某些操作在某些语句执行之前或之后执行就需要使用触发器. 例如每次插入数据时进行数据校对,每次删除数据后将删除内容备份到新表. 这些操作我们希望它(某些语句)在满足某些条件时自动执 ...

  8. 2015 UESTC 搜索专题C题 基爷与加法等式 爆搜DFS

    基爷与加法等式 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Desc ...

  9. Theme.AppCompat无全屏主题解决办法

    V7包中的Theme.AppCompat主题系列中并没有全屏样式,这个是为什么,只有作者知道…… 解决办法: 自定义主题 <style name="Theme.AppCompat.Li ...

  10. Vue学习记录-画页面

    webstorm 因为之前开发ReactNative的时候,选择了webstorm,这回转战Vue,自然还是用它.如果什么也不做的话,打开Vue工程,编辑区域基本上没有语法高亮.怎么办呢? 安装插件( ...