LeetCode Single Number II
Problem
Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
一個整型陣列,除一個元素外,其餘的元素都出現三次,要求不用額外記憶體,線性時間內找到這個元素
Python 實現
# Given an array of integers, every element appears three times except for one, which appears exactly once.
# Find that single one.
#
# Note:
# Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
# author li.hzh
class Solution:
def singleNumber (self, nums):
"""
:type nums: List[int]
:rtype: int
"""
once = twice = three_times = 0
for val in nums:
twice |= once & val
once ^= val
three_times = once & twice
once &= ~three_times
twice &= ~three_times
return once
print(Solution().singleNumber([1, 3, 1, 1, 3, 5, 3, 6, 6, 6]))
分析
這個題確實想了很久很久。最終解決問題的思路是這樣。
先是受到一個思路的啟發,就是出現三次,那麼可以把每一位的數字相加,然後除以3,把不能整除的位留下來。這個位組成的數字就是那個single number。不過這個思路需要對每個數字的每一位進行遍歷,效率不達標。但是,卻給了我很好的啟發。讓我關注每一位的元素是否為1。
用3個變數來分別記錄,元素出現1次,2次,3次對應位的情況。當出現3次後。1次和2次對應的位置就清0,最後剩下的元素的位置就儲存在1次的那個變數中。這裡利用還是異或的特性。
可以簡單的過一下這個過程。[3,3,3,2] 為例。
遍歷第一個3時,按照設計語義,twice = 1, once =3 ,three_times = 0。繼續。 第二個3,once = 0, twice = 3,(因為3出現兩次),thre3_times = 0,繼續 第三個3,once = 3, twice = 3 ,three_times = 3。重置1,2對應的位置。
如此下去,最後得到的就是2。
這裡理解的關鍵,就是once twice和three_times,不要看成具體的數字,而是對數字每一位變化情況的描述。 once 異或元素。對於某一位的變化規律是1,0,1 twice 當出現2次以上時,對應的位是1 three = once & twice ,出現3此時,自然為1。