这题真特么是太难了
解题思路
首先我们先把原数组全部异或起来,那么我们会得到一个数字,这个数字是两个不相同的数字异或的结果,我们取出其中任意一位为‘1’的位,为了方便起见,我们用 a &= -a 来取出最右端为‘1’的位。。。这道题的巧妙之处在于利用x1 ^ x2
的结果对原数组进行了分组,进而将x1
和x2
分开了。具体方法则是利用了x1 ^ x2
不为0的特性,如果x1 ^ x2
不为0,那么x1 ^ x2
的结果必然存在某一二进制位不为0(即为1),我们不妨将最低位的1提取出来,由于在这一二进制位上x1
和x2
必然相异,即x1
, x2
中相应位一个为0,另一个为1,所以我们可以利用这个最低位的1将x1
和x2
分开。又由于除了x1
和x2
之外其他数都是成对出现,故与最低位的1异或时一定会抵消,十分之精妙!
首先计算nums数组中所有数字的异或,记为xor
令lowbit = xor & -xor,lowbit的含义为xor从低位向高位,第一个非0位所对应的数字 例如假设xor = 6(二进制:0110),则-xor为(二进制:1010,-6的补码,two's complement) 则lowbit = 2(二进制:0010)
public class Solution { public int[] singleNumber(int[] nums) { int xor = 0; for(int i=0;i<nums.length;i++) { xor = xor ^ nums[i]; } int lowBit = xor & (-xor); int[] singles = new int[2]; for(int i=0;i<nums.length;i++) { if((nums[i]&lowBit)==0) { singles[0] = singles[0]^nums[i]; } else { singles[1] = singles[1]^nums[i]; } } return singles; } }
reference:
http://www.cnblogs.com/grandyang/p/4741122.html
http://bookshadow.com/weblog/2015/08/17/leetcode-single-number-iii/
http://www.kancloud.cn/kancloud/data-structure-and-algorithm-notes/72983