题目大意:给定一个整数数组,其中除两个数字只出现一次外,其余数字均出现两次。找出这两个只出现一次的数字。
例如:
给定 nums = [1, 2, 1, 3, 2, 5],返回 [3, 5]
注意:结果的顺序不重要。因此在上例中,[5, 3]也是正确的。你的算法应该满足线性时间复杂度。你可以只使用常数空间复杂度完成题目吗?
解题思路1:使用字典,利用语句:
dic[num]=dic.get(num,0)+1
对key进行计数(key分别为nums中的元素),再使用语句:
for key,value in dic.items():
对元素进行遍历,筛选出value=2的key值,最后:
if value ==1:
a.append(key)
return a
输出
代码:
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
a=[]
dic={}
for num in nums:
dic[num]=dic.get(num,0)+1
for key,value in dic.items():
if value ==1:
a.append(key)
return a
解题思路2:利用异或
首先计算nums数组中所有数字的异或,记为xor,xor为数组中两个只出现1次的数字a与b的异或。肯定不等于 b,那么说明它们的二进制位一定是不完全相同的,所以 xor肯定不为 0。也就是说,a 与 b 一定存在“某一位”,使得在它们中的某个数中是 0,而在另一个数中是 1,这是他们之间的一个差别。
例如:a=3(0011),b=4(0100),a^b=7(0111)。其中右数第1位=1,即a与b的右数第一位不相同。
令lowbit = xor & -xor,lowbit的含义为xor从低位向高位,第一个非0位所对应的数字
例如假设xor = 7(二进制:0111),则-xor为(二进制:1001,-7的补码,two’s complement)则lowbit =1(二进制:0001)。
若a与lowbit相与=1(a&lowbit==1),即a是a^b中,右数第一位为1的数,所以,a=a&0。
同理,若b与lowbit相与=0,即b是a^b中,右数第一位为0的数,b=b&0.
代码
xor = reduce(lambda: x, y: x^y, nums)
lowbit = xor & -xor #xor与xor的补码相与
a=b=0
for num in nums:
if num & lowbit:
a ^= num
else:
b ^=num
return[a,b]