剑指Offer_40

题目

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

解题思路

a. array数组中的全部元素进行异或得到 x
b. 因为两个不同的数,异或结果一定不为0, 这里假设x为6(0000 0110)
c. findLastBit在x二进制中从右往左找到第一个为1的位,右移1次(posBit)可以得到
d. 再次遍历数组,当array[i]右移posBit并和1进行与运算,可以将两个不同的数分在不同的组
e. 与此同时,num1[0]和num2[0]的它同组的元素进行异或操作,得到最终结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
private int findLastBit(int x){
int cnt = 0;
while(x != 0){
if((x & 1) == 1){
break;
}
x >>= 1;
++cnt;
}
return cnt;
}
private boolean hasBit(int target, int posBit){
return ((target >> posBit) & 1) == 1;
}
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length < 2){
return;
}
int x = 0;
for(int i = 0; i < array.length; ++i){
x ^= array[i];
}
int posBit = findLastBit(x);
num1[0] = 0;
num2[0] = 0;
for(int i = 0; i < array.length; ++i){
if(hasBit(array[i], posBit)){
num1[0] ^= array[i];
}
else{
num2[0] ^= array[i];
}
}
}
}