給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。
說明:
你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?
示例 1:
輸入: [2,2,1]
輸出: 1
示例 2:
輸入: [4,1,2,1,2]
輸出: 4
總覺得自己會了,但是優化演算法想不出來……說明還是不怎麼會啊
對於這道題,乙個很常規的思路就是所有元素異或,然後剩下的元素就是所求的元素。但是為什麼異或可以呢?
異或是把十進位制數字轉化為二進位制,然後按位異或。異或保證了出現偶數次的位數都為0,出現奇數次的位數為1,所以對所有數字異或後,出現偶數次的數字,用異或後,每位都變為0,只有出現了1次的數字保留了下來。
那麼,如果其他數字都出現了奇數次,應該怎麼辦呢?
實際上,用上面的思路也很容易想到了,假設其他數字都出現了k次,那麼我們只要能用一種運算,保證每位上出現了k次的數字都變為0,就可以找到只出現1次的數字了。
把所有數字都轉成k及以下的進製,然後對每一位求和,再對k取模,最終剩下的數字就是出現1次的數字。
不能用k以上的進製,因為這樣沒法區分該位的結果。比如,輸入[5, 4, 1, 1, 5, 1, 5], k = 3
,如果直接用10進製,對個位數相加得到22
,取模後得到1
,不知道該位應該是1
還是4
還是7
為了最省空間,使用k進製最好
注意要對負數做額外處理,因為python中負數比較特殊,所以額外寫了乙個符號位
以上思路可以推廣到任意次數,即假設其他數字出現了k次,只有1個數字出現了1次的情況。
異或版:
class
solution
:def
singlenumber
(self, nums: list[
int])-
>
int:
ans =
0for num in nums:
ans ^
= num
return ans
k進製版:
class
solution
:def
singlenumber
(self, nums: list[
int])-
>
int:
defdecimal_to_k
(num:
int, k:
int)
->
tuple
:if num <0:
is_negative =
1 num *=-1
else
: is_negative =
2 ans =
while num >= k:
num //= k
return
(is_negative, ans[::
-1])
defk_to_decimal
(k_nums:
tuple
, k:
int)
->
int:
is_negative, knum = k_nums[0]
, k_nums[1]
ans =
0for index, digit in
enumerate
(knum[::
-1])
: ans +=
(k ** index * digit)
return ans *(-
1if is_negative ==
1else1)
defoccur_once
(nums:
list
, k:
int)
->
int:
prev_sign, prev = decimal_to_k(nums[0]
, k)
for num in nums[1:
]:cur_sign, cur_k = decimal_to_k(num, k)
# num
min_length =
min(
len(prev)
,len
(cur_k)
) new_prev =
for index in
range(1
, min_length +1)
:(cur_k[
-index]
+ prev[
-index]
)% k)
new_prev.reverse(
) new_prev = cur_k[:(
len(cur_k)
- min_length)
]+ new_prev
new_prev = prev[:(
len(prev)
- min_length)
]+ new_prev
prev = new_prev
# sign
prev_sign =
(prev_sign + cur_sign)
% k return k_to_decimal(
(prev_sign, prev)
, k)
return occur_once(nums,
2)
leetcode 136 只出現一次的數字
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。說明 你的演算法應該具有線性時間複雜度。你可以不使用額外空間來實現嗎?示例 1 輸入 2,2,1 輸出 1示例 2 輸入 4,1,2,1,2 輸出 4 class solution return r...
Leetcode 136 只出現一次的數字
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。說明 你的演算法應該具有線性時間複雜度。你可以不使用額外空間來實現嗎?示例 1 輸入 2,2,1 輸出 1 示例 2 輸入 4,1,2,1,2 輸出 4 一般這種不使用額外空間,時間複雜度低的,用按...
LeetCode 136 只出現一次的數字
136.只出現一次的數字 給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。說明 你的演算法應該具有線性時間複雜度。你可以不使用額外空間來實現嗎?示例1 輸入 2,2,1 輸出 1 示例2 輸入 4,1,2,1,2 輸出 4 使用集合中沒有重複元素...