1. 原題
一個整型數組裏除了一個數字之外,其他的數字都出現了兩次。請寫程序找出這一個只出現一次的數字。
解題思路:利用異或操作的性質可以快速解決這個問題。
異或運算法則
a ^ 0 = a
——與異或等於自身;a ^ a = 0
——與自身異或等於;a ^ b ^ c = a ^ c ^ b
——交換律;a ^ b = c <=> a ^ c = b <=> b ^ c = a
;
代碼如下,複雜度:
from functools import reduce
res = reduce(lambda x, y: x ^ y, array)
print(res)
2. 變體
一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。
變體難度與解決思路
由於這一次變成了需要找到兩個思路,如果還按照原題進行異或操作,則兩個不重複的數會進行異或疊加,需要將異或疊加的狀態值拆解出來;根據異或運算法則4,則必須知道其中一個不重複數字才能拆解出另一個。
於是,考慮第一輪異或得到的結果res
,其二進制表示中,取得1的位,不重複數字和在該位上比不相同(根據異或運算0^1=1
得知);那麼找到第一個不相同的位,根據是否與該位相同把原數列劃分爲兩份,則分別包含和,再根據上一問中的解法進行求解即可,算法複雜度爲(可以進一步優化到)。
def find( array):
res = reduce(lambda x, y: x ^ y, array)
# 異或結果中爲1的是不重複數字a和b不同的位
index, res_store = 1, res # index取第一個遇見的1,根據此位把array劃分爲兩組再異或
while res & 0b1 != 1:
res, index = res >> 1, index << 1
# 跟不重複數字a在index位上相同的數字列表
a = reduce(lambda x, y: x ^ y, filter(lambda x: x & index, array))
return a, a ^ res_store # 根據 a^b=c <=> a^c=b