287. Find the Duplicate Number
題目網址:https://leetcode.cn/problems/find-the-duplicate-number/
題意:給一有
n + 1個數的 arraynums, 每個元素值皆在[1, n], 剛好只有一數字重複, 求重複的數字。注意:只能使用 $O(1)$ space, 且不能改變
nums進階:設計 $O(n)$ time 的演算法

Solution 1:
想法:利用 Binary Search, 先在
[1, n]中找中點mid, 然後判斷整個nums中≤ mid的元素個數cnt。若cnt > mid代表有重複, 則往左繼續找
 不要考慮 nums, 只需要考慮數字都在 1 到 n 之間
nums = [1,3,4,2,2] 此時數字在 1 到 4 之間
mid = (1 + 4) / 2 = 2, nums 中 ≤ 2 的有3個(1,2,2), 1到2中肯定有重複, 往左搜尋 ➔ right = 2
mid = (1 + 2) / 2 = 1, nums 中 ≤ 1 的有1個(1), 2到2中肯定有重複, 往右搜尋
➔ left = 2, left < right 不成立
➔ 所以重複的數是 2
class Solution {  | 
- time:$O(n \cdot log(n))$
- $O(log(n))$:Binary Search, while loop 得做 $O(log(n))$ 次
 - $O(n)$:while loop 每迭代一次, for loop 都得遍歷 
nums 
 - space:$O(1)$ ➔ 只需常數空間
 
Solution 2:
想法:將此問題轉換成 linked list cyle, 利用 slow & fast pointers 找出 cycle 的起點, 可參考 142. Linked List Cycle II
 nums = [1,3,4,2,2]
第一個 0 代表從 idx = 0 開始
下一個移動到 nums[0] = 1
下一個移動到 nums[1] = 3, 依此類推
因為有重複數, 代表會有兩個數指向同一個數 e.g. nums[3] 和 nums[4] 都指向 nums[2] = 4
0->1->3->2->4->2, cycle: 2->4->2
class Solution {  | 
- time:$O(n)$ ➔ 遍歷 linked list
 - space:$O(1)$ ➔ 只需常數空間
 
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
 評論
