在leetcode的第260题 Single Number III 中有位大神是这样解题的。link
public int[] singleNumber(int[] nums) {
int result[] = new int[2];
int xor = nums[0];
for (int i=1; i<nums.length; i++)
{
xor ^= nums[i];
}
int bit = xor & ~(xor-1);
int num1 = 0;
int num2 = 0;
for (int num : nums)
{
if ((num & bit) > 0)
{
num1 ^= num;
}
else
{
num2 ^= num;
}
}
result[0] = num1;
result[1] = num2;
return result;
}
核心的思想就是利用位运算,找出两个唯一的数。
首先对数组中所有的数字进行异或运算,得出的数字就是两个唯一的数的异或的值。
我将以题中给的nums = [1, 2, 1, 3, 2, 5] 为例,这里最大的是5,暂时用4位表示了,比较容易理解。那么xor
的值就是0110,这里面的两个1
就是3和5不同的位,bit
这个变量表示的是xor
中最右边的那个1
,也就是说bit
计算出来应该是0010。
在这里,解释一下int bit = xor & ~(xor-1);
这句的意义。
xor-1
的时候,会将xor
最后一个1
之后的0
都变为1
,而前面不变,也就是变成了0101,取非之后变成了1010,再与原来的xor
与得到0010。最右边的1
前面的部分0
变成了1
,1
变成了0
,所以与之后全是0
;后面的也一样,原本都是0
,被变为了1
,与后全是0;唯独这一位,与的两侧都是1
。
下面就是讲两个分开的找到的部分,这个bit
0010,两个唯一的数3 和 5只会有一个数含有这一位,那么就用bit
与其他数进行与,只有两种可能,一种是0010,一种是0000;定义两个num1
和num2
,分别与结果是0000和0010的异或,就得到了最终的两个唯一数字。
我现在喜欢python,就用python重新写了一下。
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
xor = 0
for n in nums:
xor ^= n
bit = xor & ~(xor - 1)
num1 = 0
num2 = 0
for num in nums:
if num & bit > 0 :
num1 ^= num
else:
num2 ^= num
result = [num1, num2]
return result
但是不知道为何,只是52ms,并没有体现很强的性能,还望指教。