Leetcode 142. Linked List Cycle II【数学】

题目链接:

https://leetcode.com/problems/linked-list-cycle-ii/

题意:

给定链表,求是否存在环,如果存在,求出环的入口。

分析:

可以用$map$维护。
更优的话,引用Discuss中的大神的方法——
设一个$slow$和$fast$指针,初始在头结点,$slow$每次跳一个,$fast$每次跳两个。
如果存在环,那么最终$fast$和$slow$肯定会相遇,设相遇除结点为$meeting$,环的入口结点为$entry$。
设$L1$是$head$到$entry$距离,$L2$是$entry$到$meeting$的距离,$C$是环的长度,相遇时$fast$指针在cycle里已经走过$n$圈。
由于$fast$走的路程是$slow$的两倍,因此有$2 \times (L1 + L2) = L1 + L2 + n \times C$,整理后得$L1 + L2 = C$,也就是说从$meeting$出发回到$entry$经过的距离等于从$head$走到$entry$的距离。

同样,对于Find the duplicate number,可以将下标访问看成指针的跳转,将问题转化为求环形链表中是否存在小环。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head == NULL) return head;
ListNode* slow = head;
ListNode* fast = head;
ListNode* entry = head;
while(fast->next != NULL && fast->next->next != NULL){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
while(slow != entry){
slow = slow->next;
entry = entry->next;
}
return entry;
}
}
return NULL;
}
};
文章目录
  1. 1. 题目链接:
  2. 2. 题意:
  3. 3. 分析:
  4. 4. 代码: