剑指offer 数组中只出现一次的数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次(想到异或性质:任意数字和自己异或都是0,这样每个数字从头到尾异或一遍,出现两次的数字都被消掉了)。请写程序找出这两个只出现一次的数字。
要求时间复杂度O(n),空间复杂度O(1)。
异或运算符:^
分析:
利用异或的性质;
异或每个数字,最后的结果是两个不同数字的异或结果。
想办法把两个不同的数字分到两个数组中,分别异或;
分组的方法:
- 把所有数字在二进制下看
- 成对的数字,所有bit都相同;
- 根据所有数字异或的结果,转为2进制,其结果等效于两个不同数字的异或;
- 找到该结果中,某个为1的bit位;假设为第n位;也就是说,这两个不同的数字,第n位是不相同的。
- 根据第n位是0,还是1,分为两个数组;这样两个不同的数字就分到了两组;显然成对的数字仍然会在同一组;
- 分别异或两个数组即可。
- class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int size=data.size();
if(size<2)return;
int result=data[0];
for(int i=1;i<size;i++){
result=result^data[i];
}
int n=0;
while(!(result&0x01)){
result=result>>1;
n++;
if(n>32)return;
}
int mask=0x01<<n;
*num1=0;*num2=0;
for(int i=0;i<size;i++){
if(data[i]&mask)
*num1^=data[i];
else
*num2^=data[i];
}
}
};