- 题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路分析
首先分析如果数组中只有一个数字只出现一次,在这个时候,我们可以利用一个数异或它本身等于0这个特性,从头异或至尾即可获得只出现了一次的数(此时直接在循环中进行与运算即可)。那么有两个出现一次的数时,我们可以将这个数组分成两部分,每一部分都包含一个只出现一次的数。区分的方法:
将数组中所有元素异或获得一个数设为r1,那么由于出现两次的数都被异或抵消了,r1的结果就是两个只出现了一次的数异或的结果,设这两个数为num1,num2,即num1^num2=r1,然后寻找r1中第一个为1的位的位置,设为index,则num1和num2的index位一定一个为0一个为1,根据这个方法可以将数组分成两个部分。查找第一个1位时,可以将r1与1进行与运算,如果为0则右移一位,知道与运算结果为1.index位的0、1判断可以直接右移index位,进行与运算。- 代码
bool IsBit(int num ,int index){
num=num>>index;
return num&1;
}
void FindNumsAppearOnce(vector<int> data,int *num1,int *num2) {
int size=data.size();
int r1;
for(int i=0;i<size;i++){
r1 ^= data[i];
}
int index=0;
while((r1&1) == 0){
index++;
r1=r1 >> 1;
}
*num1=0;*num2=0;
for(int i=0;i<size;i++){
if(IsBit(data[i],index)){
*num1^=data[i];
}
else{
*num2^=data[i];
}
}
}