位运算的知识点:
异或运算具有以下几个重要性质
交换律:a ^ b = b ^ a
结合律:a ^ (b ^ c) = (a ^ b) ^ c
任何数与0异或等于它本身:a ^ 0 = a
任何数与自身异或等于0:a ^ a = 0
对于数组中所有元素进行异或运算,由于相同的元素异或结果为0,所以最终结果等于a和b异或的结果:result = a ^ b。在result中找到任意为1的位(可以是a和b在二进制表示中不同的任意位),我们可以通过result & -result来得到。这样做的目的是找到a和b在该位上不同的地方,便于将它们分成两组。
根据该位上是0还是1,我们可以将数组中的所有元素分成两组,一组是在该位上为1的元素,另一组是在该位上为0的元素。因为a和b在这一位上不同,所以它们会被分在不同的组中。
然后,分别对这两组元素进行异或运算,得到两个结果,分别是a和b在该组内的异或结果。
最终,返回这两个结果,就得到了只出现一次的两个元素a和b1 3 1 2 3 5
int onceElement = 0;
for(int i = 0;i < arr.length;i++){
onceElement = onceElement^arr[i]
}
//onceElement = 10(2*5)
int span = 1;
while(onceElement & span == 0){
span <<= 1
}int group1,group2 = 0;
for(int i = 0;i < arr.length;i++){
if(arr[i] & span){
group1 ^= arr[i];
}else{
group2 ^= arr[i];
}
}
System.out.println(group1 + "\t" + group2);