如果是只有一个数字,那么当然可以直接将全部元素进行异或,最后得出那个只出现一次的元素,原理就是一个元素和自己本身异或为0,且元素之间异或的顺序不影响最后的结果。
那么如果有两个数字都出现了一次呢?可以使用HashMap来存储每个元素出现的次数,最后再进行寻找。但是我们还是要掌握一下如何使用异或来解决这个问题:
首先我们还是先将所有元素进行异或,那么我们此时得到的结果是那两个元素异或的结果,加入结果中有某一位是1,那么肯定两者之中有一个是1有一个是0。我们再将所有元素进行分组,此位置是1的到一组,此位置是0的到一组,那么要求的两个元素肯定分到了不同的组中。这样就变成了两个子问题。这两个子问题就是第一种情况,即每个数组中只有一个数字出现过一次,其它的都出现过两次。然后分别去异或就可以得到结果了:
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int result = array[0];
for(int i = 1; i < array.length; ++i)
result = result ^ array[i]; //先将所有元素进行异或
int temp = 1;
while((result & temp) == 0) temp = temp << 1; //求最末尾的一个1
int result1 = 0, result2 = 0; //这个地方要初始化为0
for(int i = 0; i < array.length; ++i) {
if ((array[i] & temp) == 0) //根据此位上为0或者1,分成两组进行异或
result1 = result1 ^ array[i];
else
result2 = result2 ^ array[i];
}
num1[0] = result1;
num2[0] = result2;
}