题目描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1).
思路解析:这个题的解题思路是按照位异或的方法。因为一个数组里面除了一个数字出现一次,其他的都是出现两次话,异或直接就出答案了。所以我们要把本题的数组分为两个。
- 把一个数组的所有数字进行异或
- 异或结果是两个出现一次的数字得到的,所以按照结果的1的位置,区分为两个数组,所以这一步是找到出现1的位置
- 然后按照此位上是否是1,分为两个数组,分别进行异或,异或结果即为出现一次的数字
代码:
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null){
return;
}
int number =0;
for(int i : array){
number^=i;//所有数字异或的结果是出现一次的两个数字的异或值
}
int index =findFirstBitIs1(number);//找到出现的最右边的1
num1[0]=0;
num2[0]=0;
for(int i : array){
if(isBit1(i,index)){
num1[0]^=i;//已经有参数了,异或结果为出现一次的数字
}else{
num2[0]^=i;//已经有参数了,异或结果为出现一次的数字
}
}
return ;
}
private int findFirstBitIs1(int x){//找到结果是1的位数
int count=0;
while((x&1)==0){
x=x>>1;//右移一位
++count;//计数是第几位
}
return count;
}
private boolean isBit1(int i,int index){//每一位都要判断是不是1
i = i>>index;//找到决定的位数
return (i&1)==0;
}
}