剑指Offer_40_数组中只出现一次的数字
题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
解题思路
两个相同的数异或得到 0,任何数和 0 异或得到原来的数。可以将所有的数异或(其实就是两个出现一次的数异或),得到一个数 a,然后判断 a 中第一位不为 0 的位,也即第一位不相同的位。然后根据该为是 1 和 0 的情况分成两组数(相同的数肯定在同一组),两组分别对组内所有数进行异或,最后就得到两个只出现一次的数。
实现
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if (array == null || array.length < 2) return;
//数组中每个数进行异或操作,得到一个不为0的数,找出其中不为1的位
//两个相同的数异或的结果为0,不同的肯定不为0。根据的到的1位,将数组分成
//那个位为0和那个为1位的子数组,两个不同的数位于不同的子数组
//然后对每个子数组中的数进行异或,得到的结果就是只出现过一次的数
int reOR = 0;
for (int i : array) {
reOR ^= i;
}
//找出1的位置
int index = findFirstOne(reOR);
num1[0] = 0;
num2[0] = 0;
for (int i : array) {
if (isOne(i,index)){
num1[0] ^= i;
}else {
num2[0] ^= i;
}
}
}
private boolean isOne(int i, int index) {
return (i & (1 << index)) != 0;
}
private int findFirstOne(int reOR) {
int count = 0;
while ((reOR & (1 << count)) == 0){
count ++;
}
return count;
}
}