142. Linked List Cycle II**
https://leetcode.com/problems/linked-list-cycle-ii/
题目描述
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
Note: Do not modify the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
Example 2:
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.
Example 3:
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.
Follow-up:
Can you solve it without using extra space?
C++ 实现 1
- 双指针方法/快慢指针
链表问题中的一个重要的方法叫双指针法。定义两个指针,一个叫慢指针,另一个叫快指针。通常慢指针每次向前移动一个节点,而快指针每次向前移动若干个节点。这个方法通常用于寻找链表中特定的位置。比如找到链表的中点,可以让快指针每次移动两个节点。这样当快指针到达链表末尾时,慢指针刚好在链表中间的位置。
假设环的起点就是 n2
(这部分内容参考 Linked List Cycle II)
n6-----------n5
| |
n1--- n2---n3--- n4|
我们仍然可以使用两个指针fast
和slow
,fast
走两步,slow
走一步,判断是否有环,当有环重合之后,譬如上面在 n5
重合了,那么如何得到 n2
呢?
首先我们知道,fast
每次比 slow
多走一步,所以重合的时候,fast
移动的距离是 slow
的两倍,我们假设 n1
到 n2
距离为 a ,n2
到 n5
距离为 b,n5
到 n2
距离为c,fast
走动距离为 a + b + c + b,而 slow
为a + b,有方程 a + b + c + b = 2 x (a + b),可以知道 a = c,所以我们只需要在重合之后,一个指针从 n1
,而另一个指针从 n5
,都每次走一步,那么就可以在 n2
重合了。
另外需要注意的是, 在 141. Linked List Cycle* 解答中, 我初始化 fast
和 slow
不在同一个节点, 在判断是否存在环时是可以这样用的, 其实就相当于, fast
和 slow
节点从某个虚拟节点出发, 前者提前走了两步, 而后者走了一步.
但此题中, 最后将 fast
和 slow
初始化为 head
, 即同时在起始节点, 只有这样操作, 最后才能达到重合时 fast
走的距离是 slow
走的距离的两倍.
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
auto slow = head, fast = head;
// 首先判断是否存在环
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
// 如果存在环, 那么开始找环
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return nullptr;
}
};