您的位置:首页 > 其它

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

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

思路:题目要求时间复杂度是O(n),空间复杂度是O(1),这说明基于比较的办法求解无法完成,这题需要异或的性质,异或(同为0,异为1,相当于不进位加法)

因为其它数都出现两次,当扫描完一次之后,将所有的数做异或,那些相同的数都会变成0,结果是两个不同的数的异或。例如,9,4,4,2做异或,4,4异或为0,结果就相当于9异或2。

这里有两个数字不同,假设只有一个数字不同,那么,我们只需要扫描一遍,所有数做异或就可以得出结果。有两个数字怎么办呢?思路就是将这两个数划分到两个不同的组去。

划分依据是什么呢?

1,可以这么做,先将所有的数异或起来,假设结果为11001100,那么可以用最低的1位划分(即第2位,低到高,从0数起)[实质上可以用任何一个1划分,只是这是最方便的],为什么1可以划分开两个不同的数呢?将两个数写成二进制的形式,那么异或结果显示出的1位(同时两个不同的数相异或必然有1,因为同则必为0),都是二者相应位不同的。(异为1,同为0),因此用1划分则不同的两数必然被分到两个不同组

2,第二步,将两个子数组的数做异或就能得出结果,因为相同的数会得0.

3,小技巧,中途需要判断位是否为1,方法是:先将要判断的位通过右移移到最末位,然后与0000.....00001做位与,末位是1,则结果是1,若末位是0,结果是0

代码:

/*一个整型数组里除了两个数字之外,其他的数字都出现了两次。
请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),
空间复杂度是O(1)*/
#include<iostream>
using namespace std;
int FindFirstbitis1(int sum)//找到第一个位是1(右往左)的索引号
{
int index=0;
while((1 & sum)==0)//和000..00001做与,若末位为0,即等于0,若末位为1,即为1
{
sum=sum>>1;
++index;
}
return index;
}
int judgeindexbitis1(int num,int index)
{
num = num >> index;//右移index位,使要判断的一位处于最末位
return(1 & num);//和000..0001与,1则返回1,0则返回0
}
void xor(int* A,int len)
{
int sum=0;//两相异的数
for(int i=0;i<len;++i)
{
sum =sum ^ A[i];
}
int index=FindFirstbitis1(sum);
int num1=0,num2=0;//保存结果
for(int i=0;i<len;++i)
{
if(judgeindexbitis1(A[i],index))
num1 =num1 ^ A[i];
else num2=num2 ^ A[i];
}
cout<<num1<<" "<<num2<<endl;
}
void main()
{
int A[]={9,0,0,3,3,8,8,55,55,8888,8888,5};
int len=sizeof(A)/sizeof(A[0]);
xor(A,len);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐