题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
题解:
就是说先把所有数据异或,然后得到的结果是两个唯一出现过一次的数的异或结果,找出他们异或结果中第一个为1的位置,说明这两个数,二进制形式在那个位置是不同的,一个为0,一个为1,我们就可以把这个位置记作k,然后把第k位为1的所有数据分在一组,为0的分在另一组,这样既能把同样的数据分为了两组,又能把两个只出现唯一一次的数据也分在了两组。我们再分别把两组的数据各自异或,就能得出这两个数了。
知识点1:找出异或和sum中,1所在的位置k
就是让sum跟1一位一位的与&,只要结果为1,那就说明那一位为1,结果不为1,那就比较sum的前(左)一位,用右移 sum = sum >> 1
知识点2:给数组里的数分组,k位为1的为1组,为0的为另一组
把数组里的数tmp右移k位,tmp = tmp >> k,然后跟1与
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int len = array.length;
if(len<2) return ;
int sum = array[0];
for(int i=1;i<len;i++){
sum = sum ^ array[i];
}
//求出第一个为1的位置
int k = 0;
while((sum&1)==0&&(k<8)){
sum = sum >> 1;
k++;
}
//把数组分成两组
for(int i=0;i<len;i++){
if(isOne(array[i],k)==1){
num1[0] = num1[0]^array[i];
}
else{
num2[0] = num2[0]^array[i];
}
}
}
public int isOne(int tmp,int k){
tmp = tmp >> k;//'右移k位
return tmp & 1;
}
}