今天來看一道有意思的題,看起來很簡單,但是要想到滿足要求的答案沒那麼容易。
有乙個非空整形陣列,除了有乙個只出現過一次的數,其他的數都出現且只出現過兩次,現要求找出這個只出現過一次的數。時間複雜度不能超過 o(n),而且不能使用額外空間。
大概意思就是,比如從 [5,5,8,8,6,9,9] 陣列中找出 6 這個只出現過一次的數。
本來可以想到對陣列先進行排序,再遍歷陣列判斷當前元素和前後元素是否相同,從而來找出那個只出現一次的元素。
但是題目要求時間複雜度不能超過 o(n),且空間複雜度為 o(1),因此陣列排序不滿足要求。
看來這道題需要使用點技巧了,我們使用位運算來試試。
遍歷陣列,對每個元素都進行異或運算。因為陣列中其他的元素都出現過兩次,兩個相同元素的異或運算結果為 0,而 0 和其他元素的異或運算結果為該元素本身,所以遍歷陣列最後只剩下那個只出現一次的那個元素。
注意位運算都是指基於二進位制的運算,所以乙個異或運算其實是先把十進位制數轉化為二進位制,然後再去做異或運算的。
這種位運算符合題目的要求,只需遍歷一遍陣列即可,時間複雜度為 o(n),也不需要額外的空間。
我們再來看一下具體的例子,來個簡單一點的陣列,[2,2,8,3,3],通過異或運算找出 8 這個數。
先把陣列中的元素全部轉換成二進位制,分別為:
#十進位制轉二進位制
2 -> 10
2 -> 10
8 -> 1000
3 -> 11
3 -> 11
接下來依次對二進位制數做異或運算,異或運算符號為 "^", 分別為:
#二進位制數異或運算
10 ^ 10 = 0
0 ^ 1000 = 1000
1000 ^ 11 = 1011
1011 ^ 11 = 1000
(注意,如果參與異或運算的兩個值位數不一致的話,前面補0)
也就是說最終我們得到的是二進位制數 1000,對應的十進位制就是數字 8。
這道題非常巧妙的利用了異或運算的特點,兩個相同的數異或結果為 0,所以陣列中相同的兩個數都相互異或為 0 了,只剩下那個只出現一次的數。
下面是一段 python 實現的**,利用異或運算找出只出現一次的數。
#python 利用異或運算找出陣列中只出現一次的數
def singlenumber(nums):
res = 0
for num in nums:
res ^= num
return res
找出陣列中只出現過一次的數
乙個大陣列,在1到25000之間,只有4k memory,列印出其中正好只出現過一次的數。沒出現過,出現過2次,3次,或更多,都不列印。solutions 1 位圖法,但每個數有3個狀態 0,1,1.因此需要2 bit,25000 2 8 1024 6.1k,記憶體占用符合要求。2 壓縮,解法1中,...
找出陣列中只出現一次的數字
乙個整型陣列裡除了乙個數字以外,其他數字都出現了兩次。找出這個只出現一次的數字 異或運算 任何乙個數字異或它本身都等於0,如果從頭到尾異或陣列中的每乙個數字,那些出現兩次的數字全部在異或中會被抵消,最終的結果剛好是這個只出現一次的數字 package jbarray 找出陣列中只出現一次的數字 au...
找出陣列中只出現一次的數字
給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。package factory description 只出現一次的數字 author jaryn date 2019 12 2 16 36 public class onenumer return...