题目:

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

思路:

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

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

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

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

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

代码:

#include <iostream>

using namespace std;

unsigned int FindFirstBitIs1(int num){
int indexBit=0;
unsigned int count=1;
while((num&count)==0){
count=count<<1;
indexBit++;
}
return indexBit;
} bool IsBit1(int num,unsigned int indexBit){
num=num>>indexBit;
return (num&1);
} void FindNumsAppearOnce(int data[],int length,int& num1,int &num2){
if(data==NULL || length<=1)
return; int resultExclusiveOR=0;
for(int i=0;i<length;i++){
resultExclusiveOR^=data[i];
} unsigned int indexOf1=FindFirstBitIs1(resultExclusiveOR); num1=0;
num2=0;
for(int i=0;i<length;i++){
if(IsBit1(data[i],indexOf1))
num1^=data[i];
else
num2^=data[i];
}
} int main()
{
int A[]={1,2,4,2,1,5,6,7,6,7};
int len=sizeof(A)/sizeof(A[0]);
int num1=0;
int num2=0;
FindNumsAppearOnce(A,len,num1,num2);
cout << num1 << " " << num2 << endl;
return 0;
}

在线测试OJ:

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

AC代码:

class Solution {
public:
bool IsBitOf1(int num,int k){
num=num>>k;
return (num&1);
} int findFirstBitOf1(int num){
int indexOf1=0;
int count=1;
while((num&count)==0){
count=count<<1;
indexOf1++;
}
return indexOf1;
} void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int length=data.size();
if(length<=1)
return; int result=0;
for(int i=0;i<length;i++)
result^=data[i]; int indexOf1=findFirstBitOf1(result); *num1=0;
*num2=0;
for(int i=0;i<length;i++){
if(IsBitOf1(data[i],indexOf1))
*num1^=data[i];
else
*num2^=data[i];
}
}
};

  

(剑指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. CentOS使用

    centos7编译安装git最新版 CentOS下 pycharm开发环境搭建之无穷无尽的问题 CentOS 7入门操作基础教程 centos中文站 CentOS7 常用命令集合 centos中有vi ...

  2. XV6操作系统代码阅读心得(一):启动加载、中断与系统调用

    XV6操作系统是MIT 6.828课程中使用的教学操作系统,是在现代硬件上对Unix V6系统的重写.XV6总共只有一万多行,非常适合初学者用于学习和实践操作系统相关知识. MIT 6.828的课程网 ...

  3. Linux内核镜像格式

    <Linux内核镜像格式>   Linux内核有多种格式的镜像,包括vmlinux.Image.zImage.bzImage.uImage.xipImage.bootpImage等. ➤k ...

  4. 基础数据类型汇总补充;集合set ;深浅copy

    首先回顾: 小数据池:int -5~256str 特殊字符,*数字20 ascii : 8位 1字节 表示1个字符unicode 32位 4个字节 表示一个字符utf- 8 1个英文 8位,1个字节 ...

  5. FastReport.Net使用:[37]报表继承

    1.设计一个基础报表,将其保存为BaseReport. 2.新建一个继承的报表. 通过 文件-->新建 打开“新建对象”向导.选择“继承的报表”,点击确定. 3. 在打开对话框中选择基础报表Ba ...

  6. [BZOJ4026]dC Loves Number Theory(线段树)

    根据欧拉函数的定义式可知,可以先算出a[l]*a[l+1]*...*a[r]的值,然后枚举所有存在的质因子*(p-1)/p. 发现这里区间中一个质因子只要计算一次,所以指计算“上一个同色点在区间外”的 ...

  7. 【最小路径覆盖】BZOJ2150-部落战争

    [题目大意] 给出一张图,'*'表示不能走的障碍.已知每只军队可以按照r*c的方向行军,且军队与军队之间路径不能交叉.问占据全部'.'最少要多少支军队? [思路] 首先注意题意中有说“军队只能往下走” ...

  8. Java并发(九):重入锁 ReentrantLock

    先做总结: 1.为什么要用ReentrantLock? (1)ReentrantLock与synchronized具有相同的功能和内存语义: (2)synchronized是重量级锁,性能不好.Ree ...

  9. bzoj 1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会 -- Tarjan

    1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会 Time Limit: 5 Sec  Memory Limit: 64 MB Description The N (2 & ...

  10. 快速幂 cojs 1130. 取余运算

    cojs 1130. 取余运算 ★   输入文件:dmod.in   输出文件:dmod.out   简单对比时间限制:10 s   内存限制:128 MB [题目描述] 输入b,p,k的值,求b^p ...