下面給出的是問題陳述和解決方案。我無法理解解決方案背後的邏輯。查找數組中的重複 - 時間複雜度<O(n^2)和常量額外空間O(1)。 (亞馬遜訪談)
問題陳述:
鑑於包含n + 1點的整數,其中每個整數是1和n(含)之間的陣列NUMS,證明至少有一個重複的數目必須存在。假設只有一個重複號碼,找到重複號碼。
注意: 您不得修改數組(假定數組是隻讀的)。 您只能使用恆定的O(1)額外空間。 您的運行時複雜度應該小於O(n2)。 數組中只有一個重複數字,但可以重複多次。
採樣輸入:[3 4 1 4 1] 輸出:用於貼在本文給出了問題1個
的解是:
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
low = 1
high = len(nums)-1
while low < high:
mid = low+(high-low)/2
count = 0
for i in nums:
if i <= mid:
count+=1
if count <= mid:
low = mid+1
else:
high = mid
return low
說明用於上述代碼(按作者): 該解決方案基於二分查找。
首先搜索空間是1到n之間的數字。每次我選擇一個數字(這是中間的數字),並計算所有等於或小於中等數字的數字。然後,如果計數超過中間值,搜索空間將爲[1 mid],否則爲[mid + 1 n]。我這樣做直到搜索空間只有一個數字。
假設n = 10,我選擇mid = 5。然後我計算數組中所有小於等於中間的數字。如果5個以上的數字小於5,那麼按照鴿王原理(https://en.wikipedia.org/wiki/Pigeonhole_principle),其中一個已經出現過一次以上。所以我縮小了從[110]到[1 5]的搜索空間。否則重複號碼在下半部分,因此下一步搜索空間將會是[6 10]。
的疑問:在上述方案中,當count <= mid
,我們爲什麼要改變low
到low = mid + 1
或以其他方式改變high = mid
? 它背後的邏輯是什麼?
我無法理解這種算法
'[3 4 1 4 1]'有兩個副本,1 4. –
實際上這個代碼容忍多個副本,並輸出最小的一個。 –
是的,如果有多個重複項,它會輸出其中的任何一個。 – kshikhar