給定乙個陣列 nums 包含 n + 1 個整數,每個整數在 1 到 n 之間,包括 1 和 n。現在假設陣列中存在乙個重複的數字,找到該重複的數字。
不能修改陣列元素,假設陣列是唯讀的。
僅可以使用常數即o(1)o(1)的額外空間。
時間複雜度需要低於o(n2)o(n2)。
陣列中僅有乙個重複數字,但它可能重複超過1次。
example 1:
input: [1,3,4,2,2]
output: 2
example 2:
input: [3,1,3,4,2]
output: 3
演算法(雙指標移動) o(n)
因為每個數都是 1 到 n,所以此題可以當做linked list cycle ii來處理。
首先first和second指標均為0,然後first每次前進一格,second每次前進兩格。i前進一格在這裡指的是nums[i]。剩餘部分請參考linked list cycle ii中的演算法證明。
時間複雜度
參見linked list cycle ii時間複雜度部分,整個陣列僅遍歷常數次,故時間複雜度為o(n)。
將陣列轉化為鍊錶形式:陣列 [1,3,4,2,2]
current / index01
234next / num[index]13
422index為當前值的索引,num[index]為下個一值的索引next index。上表中的陣列表示成煉表如下圖,方框中為index, num[index]
利用【142_環形鍊錶 ii】的方法,找到環入口,即為重複數字
設:slow指標移動速度為1,fast指標移動速度為2;slow指標在環內移動(非環部分)長度為a,slow指標在環內移動長度為b
兩指標相遇時候,slow指標移動距離為a+b,fast指標移動距離為2(a+b),可知兩指標距離差a+b即為整數倍的環長
從head移動a的距離為入環點;由2可知從head開始移動a+(a+b)的距離也為入環點,即將a點繼續移動距離a則可到達入環點
將slow指標移動回head,同時同速移動兩個指標,相遇點即為入環點
說明:因為陣列中不含0,所以不會因為index = 0, num[0] = 0導致死迴圈;對於其他位置index = num[index],若該值重複則會自身成環,若無重複則不會被遍歷到
1二分做法class
solution else16}
17return
r ;1819}
20 };
1雙指標class
solution while ( fir !=sec );
1011 fir = 0
; 12
while ( fir !=sec )
16return
fir;17}
18 };
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之...