ps:部分**參考leetcode和劍指offer。另外,三道題目都可以通過hashmap和hashset做
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。
defsinglenumber(nums):
"""異或:相同為0,不同為1
"""r =0
for i in
nums:
r ^=i
return r
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現了三次。找出那個只出現了一次的元素。
#方法一def
"""出現3次就不能再用異或的方法了,因為三個相同的數異或還是得到本身。但是還是可以採用位運算的思想,因為出現三次的數字每個位(0或者1)也是出現三次,因此可以每一位的和能夠被3整除(對3取余為0)。所以如果把每個數的二進位制表示的每一位加起來,對於每一位的和,如果能被3整除,那對應那個只出現一次的數字的那一位就是0,否則對應的那一位是1。
我們需要用乙個陣列bitsum儲存每一位的和,具體來講實現過程是,先初始化為0,然後對於每個數字,遍歷它二進位制表示的每一位,如果這一位是1,bitsum對應的那一位就加1。
"""if
notarr:
return
max_length = max([len(bin(x)) for x in
arr])
bits_count = [0] *max_length
for x in
arr:
bit_mask = 1 #
對於每個數都從最低位開始判斷
for bit_index in range(max_length - 1, -1, -1):
if x & bit_mask !=0:
bits_count[bit_index] += 1bit_mask = bit_mask << 1result =0
for count in
bits_count:
result = result << 1 #
先把當前結果左移到高位
result += count % 3 #
然後把當前位應該為0還是1填上去
return
result
#方法二
def seen_once = seen_twice =0
for num in
nums:
##add num to seen_once
#don't add to seen_twice because of presence in seen_once##
remove num from seen_once
#add num to seen_twice##
don't add to seen_once because of presence in seen_twice
#remove num from seen_twice
seen_once = ~seen_twice & (seen_once ^num)
seen_twice = ~seen_once & (seen_twice ^num)
return
seen_once
#方法三,對方法二的解釋
def one =0
two =0
for num in
nums:
#two的相應的位等於1,表示該位出現2次
two |= (one &num)
#one的相應的位等於1,表示該位出現1次
one ^=num
#three的相應的位等於1,表示該位出現3次
three = (one &two)
#如果相應的位出現3次,則該位重置為0
two &= ~three
one &= ~three
return
one
給定乙個整數陣列nums
,其中恰好有兩個元素只出現一次,其餘所有元素均出現兩次。 找出只出現一次的那兩個元素。
"""從頭到尾一次異或陣列中的每乙個數字,那麼最終得到的結果就是兩個只出現一次的陣列的異或結果。因為其他數字都出現了兩次,在異或中全部抵消了。
由於兩個數字肯定不一樣,那麼異或的結果肯定不為0,也就是說這個結果陣列的二進位制表示至少有乙個位為1。
我們在結果陣列中找到第乙個為1的位的位置,記為第n位。
現在我們以第n位是不是1為標準把元陣列中的數字分成兩個子陣列,第乙個子陣列中每個數字的第n位都是1,而第二個子陣列中每個數字的第n位都是0。
"""def
ifnot arr or len(arr)<2:
return
res =0
for i in
arr:
res = res^i
index =find_first_bit_is_1(res)
num1 =0
num2 =0
for i in
arr:
ifis_bit_1(i,index):
num1 = num1^i
else
: num2 = num2^i
return
num1,num2
deffind_first_bit_is_1(num):
"""找到num的二進位制位中最右邊是1的位置
"""index_of_bit =0
while num != 0 and num & 1 ==0:
num = num >> 1index_of_bit += 1
return
index_of_bit
defis_bit_1(num,index):
"""判斷第index位是不是1
"""num = num>>index
return num&1
if__name__ == "
__main__":
只出現一次的數字
1.乙個整型陣列,有乙個數字出現一次,其餘數字出現兩次,找出這個只出現一次的數字。解題思路 異或運算性質 兩個相同的數字異或得0,0與乙個數字異或得數字本身,而且異或運算是滿足交換律的 陣列元素按位異或,交換律可以想象成相同的數字參與運算的時候是相鄰的 所有出現兩次的數字異或之後得0,最後剩餘的是0...
只出現一次的數字
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。說明 你的演算法應該具有線性時間複雜度。你可以不使用額外空間來實現嗎?示例 1 輸入 2,2,1 輸出 1示例 2 輸入 4,1,2,1,2 輸出 4核心思想 對list排序,然後遍歷 class ...
只出現一次的數字
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素 例 1,2,2 1 方法一 異或 數字1 數字2 每一位如果相同就為0,不同為1 1 1 0 1 0 1 0 1 1 0 0 0 class solution def singlenumber se...