题目
一个数组,(1)只有一个数值出现次数为奇,剩下所有数字出现次数都是偶,求这个数。(2)该数组中有两个数出现次数都为奇,剩余数字出现次数都为偶,求这两数。
解题(1)
- 分析
根据异或的性质,相同数值异或等于0可得出,只要将整个数组全部异或,最后偶数次出现的数就会被归0,只剩下奇数次的数。
- 操作代码(Java)
public void tatic Num1(int[] arr){
int eor = 0 ;
for(int i =0 ;i<arr.length;i++){
eor ^= arr[i];
}
system.out.println(eor)
}
解题(2)
- 分析
和(1)一样,当我们把整个数组异或完之后,得到eor=a^b(这里定义异或结果变量名为eor)剩下的就是两个出现奇数次的数相互异或a^b。
我们可以这样思考,这两个数的值不同,那么他们异或结果不为零,也就是说他们在某一位上一定不同,有异或结果的某一位上一定为1。那么我们找到这个1的位置,再去整个数组筛选一遍,这一位上为1的数全部异或,最后得到的一定是a,b其中一个,再用它去异或之前的eor得到另一个数。
- 操作代码(Java)
public void static Num2(int[] arr){
int eor = 0 ;
for(int i =0 ;i<arr.length;i++){
eor ^= arr[i];
}
onlyone = 0
rightone = eor&(~eor-1)//找到这个数最右边的1
for(int i = 0;i<arr.length;i++){
if(arr[i]&rightone == 0 ){
onlyone ^=arr[i]
}
}
system.out.println(eor+""+(onlyone^eor))
}
- 如何找到这个数最右边的1
在写代码时经常会用到,下面就是找该数最右边的
rightone = eor&(~eor-1)