题目
一个整型数组里除了两个数字之外,其他的数字都出现两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
{2,4,3,6,3,2,5,5} 结果为4,6。
异或运算的特性
- 交换律 a^b = b^a
- 结合律 a^b^c = a^(b^c)
- a^a = 0
- 0^a = a
- a^b^a = a^a^b = b
- 如果a^b = 1 != 0,则a与b的二进制形式的个位是不相同的
结题思路
只有一个数字只出现一次
题目如果改为只有一个出现一次的数字。
根据特性5,我们只需要把所有的数字一起异或就会得到这个只出现一次的数字N.
N = 0^A[0]^A[1]^A[2]….
两个数字只出现一次
1) x = n^m = 0^A[0]^A[1]^A[2]….
根据特性6我们知道如果n,m不相等.他们异或的结果的二进制形式的每一位都代表n,m二进制对应位不相同。例如两个二进制数字a,b异或:10011^11011 = 1000 , 二进制结果中只有第四位数字等于1,则a,b的第四位不同。
2)挑选所有元素异或结果x的其中一个为1的位置不变,其他位置变为0,得到y.假设x的二进制形式为10110,y=10000.
3)每个元素与y进行与运算,结果为等于y的是一组,结果不为y的是一组。n和m一定不在同一组。
4)问题转化为只有一个数字只出现一次
代码
1 | public class TestXor { |