一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。要求时间复杂度是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),这说明基于比较的办法求解无法完成,这题需要异或的性质,异或(同为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); }
相关文章推荐
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组里除了一个数字之外,其他的数字都出现了两次。要求时间复杂度是O(n),空间复杂度是O(1),如何找出数组中只出现一次的数字
- 一个数组中除了两个数字之外,其余数字均出现了两次,如{1,2,3,4,5,3,2,1}.查找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次,请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次,请写程序找出这两个出现一次的数字
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字