leetcode 287 尋找重複數

2021-10-08 10:50:42 字數 1441 閱讀 4684

287. 尋找重複數

給定乙個包含 n + 1 個整數的陣列 nums,其數字都在 1 到 n 之間(包括 1 和 n),

可知至少存在乙個重複的整數。假設只有乙個重複的整數,找出這個重複的數。

示例 1:

輸入: [1,3,4,2,2]

輸出: 2

示例 2:

輸入: [3,1,3,4,2]

輸出: 3

說明:不能更改原陣列(假設陣列是唯讀的)。

只能使用額外的 o(1) 的空間。

時間複雜度小於 o(n2) 。

陣列中只有乙個重複的數字,但它可能不止重複出現一次。

思路:這道題要求我們查詢的數是乙個整數,並且給出了這個整數的範圍(在 1 和 n 之間,包括 1 和 n),並且給出了一些限制,於是可以使用二分查詢法定位在乙個區間裡的整數;

二分法的思路是先猜乙個數(有效範圍 [left, right]裡的中間數 mid),然後統計原始陣列中小於等於這個中間數的元素的個數 cnt,如果 cnt 嚴格大於 mid,(注意我加了著重號的部分「小於等於」、「嚴格大於」)。根據抽屜原理,重複元素就在區間 [left, mid] 裡;

與絕大多數二分法問題的不同點是:正著思考是容易的,即:思考哪邊區間存在重複數是容易的,因為有抽屜原理做保證。我們通過乙個具體的例子來分析應該如何編寫**;

以 [2, 4, 5, 2, 3, 1, 6, 7] 為例,一共 8 個數,n + 1 = 8,n = 7,根據題目意思,每個數都在 1 和 7 之間。

例如:區間 [1, 7]的中位數是 4,遍歷整個陣列,統計小於等於 4 的整數的個數,如果不存在重複元素,最多為 4 個。等於 4的時候區間 [1, 4] 內也可能有重複元素。但是,如果整個陣列裡小於等於 4 的整數的個數嚴格大於 4 的時候,就可以說明重複的數存在於區間 [1, 4]

class

solution

:def

findduplicate

(self, nums: list[

int])-

>

int:

left, right =0,

len(nums)-1

while left < right:

#每次找乙個中位數

mid =

(left + right)//2

cnt =

0#計算得到比中位數小於等於的值的個數

for num in nums:

if num <= mid:

cnt +=

1if cnt > mid:

#如果比mid小於等於的值的個數大於mid,那麼重複的數肯定在mid左邊

right = mid

else

:#否則,重複的數在mid右邊

left = mid +

1return left#最後彈出left,就是為重複值

LeetCode 287 尋找重複數

參考 給定乙個包含 n 1 個整數的陣列 nums,其數字都在 1 到 n 之間 包括 1 和 n 可知至少存在乙個重複的整數。假設只有乙個重複的整數,找出這個重複的數。示例 1 輸入 1,3,4,2,2 輸出 2示例 2 輸入 3,1,3,4,2 輸出 3說明 不能更改原陣列 假設陣列是唯讀的 只...

LeetCode 287(尋找重複數)

給定乙個包含 n 1 個整數的陣列 nums,其數字都在 1 到 n 之間 包括 1 和 n 可知至少存在乙個重複的整數。假設只有乙個重複的整數,找出這個重複的數。示例 1 輸入 1,3,4,2,2 輸出 2示例 2 輸入 3,1,3,4,2 輸出 3說明 不能更改原陣列 假設陣列是唯讀的 只能使用...

leetcode287 尋找重複數

1.二分查詢 參考 可以認為有兩個陣列,乙個是原陣列,乙個是1 n的範圍陣列 無重複 每次對low high的範圍陣列做二分,取中間數mid,然後去原陣列中統計小於等於mid的數目,如果大於mid 如果無重複,那麼應該小於等於mid 說明重複的那個數字在1 mid之間,結合範圍即在 low mid之...