异或运算的性质和扩展

48 篇文章 0 订阅
46 篇文章 0 订阅

0 ^ N = N
N ^ N = 0

1.一个数组中有一种数字出现了奇数次,其他数字出现了偶数次,怎么找到这一个数

private int getOddTime(int[] arr){
	in odd = 0;
	for (int i : arr){
		odd = odd ^ i;
	}
	return odd;
}

2.一个数组中有两种数出现了奇数次,,其他数都出现了偶数次,怎么找到这两个数

【思路】:这边同样也是用异或,除了两种数出现奇数次,其他都是偶数次,那么全部异或,结果必然是和出现奇数次的2种数的异或结果一致,假设出现奇数次的数字分别是a和b,所有数字异或的结果==a^b,
设a ^ b = odd
取odd最低位1,也就是二进制位从右往左第一个1所在的位置,其余均置为0,设为flag,而这个为1的位,a和b必定只有一个数字在这个二进制位数字是1(其实不取最低位为1的也可以,任意位置为1的都可以)
遍历数组,所有与flag相与为1的数字都进行异或,这样就排除掉a,b中在该位置是1的数字,其余数都是偶数次,异或结果为0,0^(两种数中的一个)结果就是其中一个数字,假设该数字是a,
a ^ b = odd,
0 ^ a = a,
a ^ b ^ a = b = odd ^ a
这样就求出了2个数字

private int[] getOdds(int[] arr){
	int odd = 0;
	for (int i : arr){
		odd = odd ^ i;
	}
	int flag = odd & (~odd + 1);//取最低位1
	int odd1 = 0;
	for (int i : arr){
		if (i & flag == 1){
			odd1 = odd1 ^ i;
		}
	}
	return [odd1,odd0^odd1];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值