Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
这道题是第141题的加强版,要求找到链表回环的入口,难度为Medium。
这里仍旧用快慢指针法来解决,我们知道fast和slow必定在回环上某节点相遇,而且slow还未走完第一圈。假定fast和slow在P处相遇,见下图。
此时让fast回到链表表头S然后每次遍历一个节点,slow保持不变继续从P每次遍历一个节点,这样fast和slow会在P处再次相遇。为什么呢?因为初次相遇时fast走的距离是slow的两倍,因此再走相同的时间后slow走到P(和初次相遇前fast走的路程相同),而fast也会走到P(和初次相遇前slow走的路程相同),最后从M到P这一段二者是重叠的,因而fast和slow相等的节点就是回环的入口。代码如下:
/**
* 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) {
ListNode *p = head;
ListNode *q = head;
while(q) {
p = p->next;
q = q->next;
if(!q) return NULL;
else q = q->next;
if(p == q) {
q = head;
while(p != q) {
p = p->next;
q = q->next;
}
return p;
}
}
return NULL;
}
};