标签:log -- 不同 计算 return 剑指offer 简化 and 函数
//除了两个数字 A和B不相等 所以异或完以后的C C为1的某一位上 A和B在这一位上肯定是相异的 //不然不会异或为1 所以按这一位上为零或者为1来把数组分为两个 //因为同一个数是不可能被分到两个组的 //简化为只有一个数字外 其余都出现两次的这个问题 class Solution { public: int find(int num) { int result=0; while(((num&1)==0)&&result<32) { num=num>>1; ++result; } return result; } int panduan(int a,int weiyi) { a=a>>weiyi; if((a&1)==1) { return 1; } else { return 0; } } void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { if(data.size()<2) { return ; } //依次异或 留下的就是两个不同的数异或的结果 int temp=0; for(int i=0;i<data.size();++i) { temp^=data[i]; } //找出某一个为1的位置; 作为判据分组; 这里需要两个函数 int weizhi=find(temp); for(int i=0;i<data.size();++i) { if(panduan(data[i],weizhi)==1) { num1[0]^=data[i]; } else { num2[0]^=data[i]; } } } };
我们换一个角度来看,如果数组中没有x,那么数组中所有的数字都出现了3次,在二进制上,每位上1的个数肯定也能被3整除。如{1, 5, 1, 5, 1, 5}从二进制上看有:
1:0001
5:0101
1:0001
5:0101
1:0001
5:0101
二进制第0位上有6个1,第2位上有3个1.第1位和第3位上都是0个1,每一位上的统计结果都可以被3整除。而再对该数组添加任何一个数,如果这个数在二进制的某位上为1都将导致该位上1的个数不能被3整除。因此通过统计二进制上每位1的个数就可以推断出x在该位置上是0还是1了,这样就能计算出x了。
推广一下,所有其他数字出现N(N>=2)次,而一个数字出现1次都可以用这种解法来推导出这个出现1次的数字。
标签:log -- 不同 计算 return 剑指offer 简化 and 函数
原文地址:http://www.cnblogs.com/159269lzm/p/7265777.html