1:题目
给定一个整数数组aar,其中只有两个数出现了奇数次,其他的数都出现了偶数次,找出这个数。
例如:
aar=[1,5,1,5,2,6,4,6],
返回2,4
2:要求
要求时间的复杂度为O(n),额外的空间复杂度为O(1)
3:解答
1:首先可以知道整数k和0异或的结果为k,整数k和k异或的结果为0,这是异或的规律。
2:如果只有一个数出现奇数次,比如array=[2,3,3],那么通过异或操作,最后获取到的结果就是我们需要找的数2。
这是什么原因呢?可以举例说明一下,
2的二进制是0010,3的二进制是0011,那么2^3的结果是0001,再次和3异或,结果为0010,而0010的十进制是2,
异或运算符满足交换律和结合律,同时结合1所说的规律,所以任意调整数组的位置不会改变运算的结果。
对于任何的数组,只要这个数组有一个数出现了奇数次,另外的数出现了偶数次,最后异或的结果都是出现了奇数次的数。
代码可见下面的代码部分。
那么如果有2个数出现奇数次,我们可以用同样的方法考虑。
a:首先申请一个变量x,那么数组最后异或的结果肯定是两个出现奇数次的数的异或结果,把它赋值给x。
b:x肯定能在32的位整数中找到不等于0的bit位,假如第k位不等于0,说明这两个出现奇数次的数,一个数在第k位为0,一个在第k位为1。
c:接下来再次对这个数组分组,一个数组是第k位都是0的数的组合,另一个数组是第k位都是1的数的组合。
那么这个分组怎么分呢 ???思考一下......
一个数n的相反数可以直接~n+1,一个数和自己的相反数进行位与,得到的是原数中右起第一个为1,其余都为0的数。
比如5的原码 00000000 00000000 00000000 00000101
则-5在计算机中表达为:11111111 11111111 11111111 11111011
d:再分别对两个数组进行各自的异或操作,两个数组获取到的结果就是我们需要找的两个数。
4:代码
如果你觉得这篇文章有用,记得分享关注下面的公众号,大家一起进步哦~~~
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎留言投稿~
如果你喜欢,请留下你的赞哦