1.数组内存在一个个数为奇数的数,其余数个数都为偶数,求这个数。
解决该问题要用到位运算中的异或,首先要了解异或的特性:
1.a ^ 0 = a
2.a ^ a = 0
3.异或满足交换律和集合律:a ^ b = b ^ a, a ^ b ^ c = a ^ (b ^ c)
因此面对该问题,可以将数组内的数全部异或,由于其余数为偶数个,异或结果最终为0,奇数个的数异或后会剩下一个,因此可以求出该数
2.数组内存在两个不相同的个数为奇数的数,其余数个数都为偶数,求这两个数。
假设这两个数为a,b,由上述特性可知异或后的结果result为a ^ b,因为a和b不相同,因此a ^ b的结果(result)里必定存在一位为1。通过这个1可以将a和b区分开:
将数组里该位为1的数进行异或,因为a和b该位不同,因此肯定能将它们分开,而由于其他数的个数都为偶数,所有异或后又只剩下了a或b其中的一个,最后将result异或新的结果,便能得到另一个数。
a := []int{11, 11, 5, 5, 8, 8, 7, 7, 7, 3, 3, 3} //两个不相同的数个数为奇数,其余数个数为偶数
result := 0
for _, v := range a {
result ^= v //假设两个数为a,b 异或后result结果为a^b
}
one := 0
right := result & (^result + 1) //因为a不等于b所有result不为0,存在至少一位为1,通过result & (^result + 1)得到最右边为1的一位,a和b在这位上不相同
for _, v := range a {
if v&right == right { //通过v&right == right可以将a和b分开,等式右侧可以换成0
one ^= v //最终异或结果会只剩下a或b其中一个
}
}
fmt.Println(one, one^result)
标签:right,运算,奇数,个数,偶数,异或,result
From: https://www.cnblogs.com/tjhzdsa/p/18144680