這一題我想的方法就很不優雅,想用map,每次插入的時候查看是否已經存在這個元素了
但是看了一下題解,用的都是快慢指針的思想
於是搜索了一下:Floyd 判圈算法
Floyd 判圈算法,又稱龜兔賽跑算法,它是一個檢測鏈表是否有環的算法。
原理:
-
判定是否有環: 假設 t 和 h 同時從起點 S 出發, t 的步長是一步, h 的步長是兩步, 如果有環, 則 t 與 h 一定會在環上一點相遇, 記爲 M.
-
環的長度: 如果判定有環, h 不動, t 繞環一圈回到 h, 就是環的長度.
-
環的起點: h 仍不動, t 回到起點 S, 這時候 t 按原路徑走到 h 的距離, 是環的整數倍. 這時候 t 和 h 同時以相同步長(只能是一步)前進, 相遇處便是環的起點, 記爲 P.
我們對 nums[] 數組建圖,每個位置 i 連一條i→nums[i] 的邊。由於存在的重複的數字target ,因此 target這個位置一定有起碼兩條指向它的邊,因此整張圖一定存在環,且我們要找到的target 就是這個環的入口
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int slow = 0, fast = 0;
do {
slow = nums[slow]; //slow每次走一步
fast = nums[nums[fast]]; //fast每次走兩步
} while (slow != fast);
slow = 0; //相遇之後將slow置回到起點
while (slow != fast) { //再相遇的時候就是環起點時候
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
};