LeetCode287 尋找重複數

2021-09-27 19:06:37 字數 1785 閱讀 9864

題目的限制真多!!!

首先 不能改變陣列 導致無法排序,也無法用 index 和元素建立關係;

只能使用 o(1) 的空間 意味著使用雜湊表去計數這條路也走不通;

時間複雜度必須小於 o(n^2) 表示暴力求解也不行;

重複的元素可重複多次 這一條加上後,本來可以通過累加求和然後做差 sum(array) - sum(1,2,…,n) 的方式也變得不可行。

本來是非常簡單的一道陣列遍歷的題目,加上了上面這四個條件後感覺有點無從下手。

我們說做題要借助演算法,而不是空想,因此對於這道題也不例外,我們可以問自己這樣乙個問題,就是 「什麼樣的演算法可以不使用額外的空間解決陣列上面的搜尋問題?」。

靜靜的思索一下。

你這時應該隱隱約約知道了,難道是 二分查詢!

什麼?二分查詢法?!

二分查詢法不是對有序陣列才適用麼?

這裡澄清乙個誤區,二分法的使用 並不一定 需要在排序好的陣列上面進行,不要讓常見的例題限制了你的思路,二分法還有乙個比較高階的用法叫做 按值二分。

這道題目交代的資訊很少,我們只需要關注兩個東西 - 陣列,陣列裡的元素,利用二分我們需要去思考的是,我們要找符合條件的元素作為答案,那麼 比答案小的元素具有什麼樣的特質,比答案大的元素又具有什麼樣的特質?,結合題目給我們的例子來看看:

( 說明:下面的 <= 符號表明 小於或者等於。)

例1:[1,3,4,2,2] 元素個數

<= 1 的元素:1 1

<= 2 的元素:1, 2, 2 3

<= 3 的元素:1, 2, 2, 3 4

<= 4 的元素:1, 2, 2, 3, 4 5

例2:[3,1,3,4,2]

<= 1 的元素:1 1

<= 2 的元素:1, 2 2

<= 3 的元素:1, 2, 3, 3 4

<= 4 的元素:1, 2, 3, 3, 4 5

極端一點的例子 (必須保證陣列的長度是 n + 1, 並且元素都在區間[1,n] 上, 有且只有乙個重複)

[3,3,3,3,4]

<= 1 的元素: 0

<= 2 的元素: 0

<= 3 的元素:3, 3, 3, 3 4

<= 4 的元素:3, 3, 3, 3, 4 5

看完上面幾個例子,相信你明白了乙個事實:

「如果選中的數 小於 我們要找的答案,那麼整個陣列中小於或等於該數的元素個數必然小於或等於該元素的值;

如果選中的數 大於或等於 我們要找的答案,那麼整個陣列中小於或等於該數的元素個數必然 大於 該元素的值」

而且你可以看到,我們要找的答案其實就處於乙個分界點的位置,尋找邊界值,這又是二分的乙個應用,而且題目已經告訴我們陣列裡面的值只可能在 [1, n] 之間,這麼一來,思路就是在 [1, n] 區間上做二分,然後按我們之前提到的邏輯去做分割。整個解法的時間複雜度是 o(nlogn),也是滿足題目要求的。

上面的解法不是最優的,但是個人覺得是根據現有的知識比較容易想到的。

#include using namespace std;

int main();

int len=sizeof(a)/sizeof(a[0]);

int start=1,length=len-1;

while(startmid) length=mid;

else start=mid+1;

}cout<

return 0;

}

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之...