leetcode 287. Find the Duplicate Number | 287. 寻找重复数(判断链表是否有环,并找到环的起点)
題目
https://leetcode.com/problems/find-the-duplicate-number/
題解
題目有限制 不能修改數組元素,必須 O(1) 空間復雜度,所以 不能排序,不能用 set / map
因為本題具有 所有數字都在 1 到 n 之間 的特點,所以天然的(出題人故意的)可以當做一個鏈表來處理。
官方題解 利用了與 “找到環形鏈表的第一個起點” 相同的思路。
Approach 3: Floyd’s Tortoise and Hare (Cycle Detection)
Intuition
The idea is to reduce the problem to Linked List Cycle II:
Given a linked list, return the node where the cycle begins.
First of all, where does the cycle come from? Let’s use the function f(x) = nums[x] to construct the sequence: x, nums[x], nums[nums[x]], nums[nums[nums[x]]], ....
Each new element in the sequence is an element in nums at the index of the previous element.
If one starts from x = nums[0], such a sequence will produce a linked list with a cycle.
The cycle appears because nums contains duplicates. The duplicate node is a cycle entrance.
Here is how it works:
Now the problem is to find the entrance of the cycle.
Algorithm
Floyd’s algorithm consists of two phases and uses two pointers, usually called tortoise and hare.
In phase 1, hare = nums[nums[hare]] is twice as fast as tortoise = nums[tortoise]. Since the hare goes fast, it would be the first one who enters the cycle and starts to run around the cycle. At some point, the tortoise enters the cycle as well, and since it’s moving slower the hare catches the tortoise up at some intersection point. Now phase 1 is over, and the tortoise has lost.
Note that the intersection point is not the cycle entrance in the general case.
To compute the intersection point, let’s note that the hare has traversed twice as many nodes as the tortoise, i.e. 2d(tortoise)=d(hare), that means
(F+a)=F+nC+a, where n is some integer.
Hence the coordinate of the intersection point is F+a=nC.
In phase 2, we give the tortoise a second chance by slowing down the hare, so that it now moves with the speed of tortoise: tortoise = nums[tortoise], hare = nums[hare]. The tortoise is back at the starting position, and the hare starts from the intersection point.
Let’s show that this time they meet at the cycle entrance after F steps.
- The tortoise started from zero, so its position after F steps is F.
- The hare started at the intersection point F+a=nC, so its position after F steps is nC+F, that is the same point as F.
- So the tortoise and the (slowed down) hare will meet at the entrance of the cycle.
Implementation
class Solution {public int findDuplicate(int[] nums) {int fast = nums[0];int slow = nums[0];do {fast = nums[nums[fast]];slow = nums[slow];} while (fast != slow);slow = nums[0];while (fast != slow) {fast = nums[fast];slow = nums[slow];}return fast;} }Result
總結
以上是生活随笔為你收集整理的leetcode 287. Find the Duplicate Number | 287. 寻找重复数(判断链表是否有环,并找到环的起点)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 658. Find K
- 下一篇: leetcode 284. Peekin