# Floyd's cycle detection
## 步驟
1. 龜兔同時從起點出發,兔的速度是龜的兩倍,若兩者相遇代表有 cycle 存在。
2. 第一次相遇後,龜回到起點,兔在原地。
3. 龜兔同時出發,但這次速度相同,兩者相遇的地點即是 cycle 開始處。
## 證明
假設龜速 = 1,兔速 = 2,開頭到 cycle 的距離 = m,cycle 長度 = r
第一次相遇時龜走了 k 步,兔走了 2k 步。
$$
k = m + ar + x
\\
2k = m + br + x
$$
x 代表從 cycle 起始處到相遇位置的距離,a、b 是正整數。
$$
k = (b - a) \times r
$$
代表 k 是 r 的正整數倍。
所以可以得出
$$
k = m + ar + x = (b - a) \times r
\\
m + x = (b - 2a) \times r
$$
(b - 2a) 一樣也是正整數,所以當龜從頭開始,而兔從第一次相遇處一起走同樣速度,第二次相遇的點就會是 cycle 開始處。
(以龜的觀點來看是 m,以兔的觀點來看是 $m + br + x + m = m + (2b-2a) \times r$)
## 應用在 Leetcode 287. Find the Duplicate Number
這題也可以看做是一個具有 cycle 的 list,因為 array 中的值會跳到下一個值,並且除了一個數以外都不會重複。而重複的那個數正是 cycle 的開始處,因為有兩個以上的位置會跳到同一個值。
```c=
int findDuplicate(int* nums, int numsSize){
int slow = nums[0];
int fast = nums[0];
do
{
slow = nums[slow];
fast = nums[nums[fast]];
} while (slow != fast);
slow = nums[0];
while (slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
```