出现一次的数字(其他数字出现三次,两次)

 位运算的知识点:
 

异或运算具有以下几个重要性质
交换律: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和b

1 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);

出现一次的数字(其他数字出现三次,两次)_第1张图片

 出现一次的数字(其他数字出现三次,两次)_第2张图片

或运算的最小翻转次数:
出现一次的数字(其他数字出现三次,两次)_第3张图片

你可能感兴趣的:(算法,java,算法,数据结构)