leetcode【260】Single Number III
阿新 • • 發佈:2018-11-13
寫在最前面:
當然可以通過遍歷查詢,但是時間複雜度太高,leetcode肯定通不過。
然後我們要研究異或。
leetcode【260】Single Number III
Given an array of numbers nums
, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
Example:
Input:[1,2,1,3,2,5]
Output:[3,5]
Note:
- The order of the result is not important. So in the above example,
[5, 3]
is also correct. - Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
首先給出很常規的解法:
class Solution(object): def singleNumber(self, nums): """ :type nums: List[int] :rtype: List[int] """ length = len(nums) res = [] newnum = [] for i in range(length): for j in range(i+1,length): if nums[i] == nums[j]: res.append(nums[j]) if nums[i] not in res: newnum.append(nums[i]) return newnum
借鑑一下大神的思路吧,前方高能!
關鍵思路是,只有兩個數不同,那麼我們需要一遍異或,這個異或的值是什麼呢,是兩個不同的數的異或值,然後我們用mark標記這這個異或值其中哪一位是1,因為這個異或值只有兩個1,這兩個1區分了不同的兩個數。假設3,5是不同的數,異或為6,即0110,那麼我們就可以拿0100和0010去遍歷所有數,進行與操作,與操作的規則是隻有兩個都為1,結果才為1,其餘都是0。只要遍歷結果為0000,即為0,那麼我們就找到了這個數。
而大神的程式碼效率高在於他找到第一個為1的數,即0010後,沒有再找下一個,那麼這個0010遍歷所有數後只能找到一個不同的數,神奇的在於,除去一個不同的數,假設是3,那麼剩下所有的數相異或的結果就是另一個不同的數,5!
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
xor = 0
num1, num2 = 0, 0
for num in nums:
xor ^= num
mask = 1
while xor & mask == 0:
mask = mask << 1
for num in nums:
if num & mask == 0:
num1 ^= num
else:
num2 ^= num
return [num1, num2]
下面是我理解了思路自己寫的,即使關鍵部分用了異或和與運算,還是在leetcode上超時。 主要是因為我找到兩個mark,分別去遍歷所有數,導致時間複雜度高。
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
xor = 0
num1, num2 = 0, 0
if len(nums) == 2:
return nums
for num in nums:
xor ^= num
mask1 = 1
while xor & mask1 == 0:
mask1 = mask1 << 1
mask2 = mask1 << 1
while xor & mask2 == 0:
mask2 = mask2 << 1
for num in nums:
if num & mask1 == 0:
num1 ^= num
elif num & mask2 == 0:
num2 ^= num
return [num1, num2]