首先有这样一个问题:如果有一个数组,除了一个数字出现了一次,其余数字都出现了两次,求这个出现了一次的数字。
这个问题的解法只需要将数组中所有的数字都进行异或,最后的结果就是只出现了一次的数字。原因是任何两个相同的数字异或结果都为0,并且异或满足交换律。
而对于数组中出现了2个只出现一次的数字,将所有数字都异或之后的结果为这两个数字的异或。这个异或结果一定不为0,因此可以从中任意选择某一个不为0的位,将整个数组划分位这一位为0和为1两个分组。
比如两个只出现一次的数字分别为2和1,将整个数组异或之后的结果为11,选择1进行划分,则所有数组中的数字被分为1这一位上为0和1这一位上为1两个分组。
在每一个分组中,都满足除了一个数字出现了一次,其余数字都出现了两次,因此可以直接对所有数字进行异或得到结果。
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
total = nums[0]
for i in range(1, len(nums)):
total ^= nums[i]
# 查找total不为0的任意1位
diff = 1
while total & diff == 0:
diff <<= 1
# 根据diff位是否为1将nums分为2个数组
group = [[],[]]
for num in nums:
if diff & num == 0:
group[0].append(num)
else:
group[1].append(num)
results = []
for g in group:
result = g[0]
for i in range(1, len(g)):
result ^= g[i]
results.append(result)
return results