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?
主要思路:
判断是否有环仍然是使用快慢指针法。怎么找到环的起点就需要一点分析了。
假设P1是慢指针,而P2是快指针。P1和P2在相遇前所走过的路程分别为 2+1 和 2+3+1。更具普遍意义的路程应该如下:
记len=从head到入口的距离,记round=环的长度,记x为相遇点到入口的距离,我们有2*(len+x) = round+x+len,即len+x = round
也就是len = round-x。显然如果此时有一个指针从head开始一步一步移动,而P1从相遇点一步一步移动,他们将相遇在环的入口处。
代码如下:
/**
* 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* P1 = head;
ListNode* P2 = head;
while(P2)
{
if(P2->next==NULL)
return NULL;
P1 = P1->next;
P2 = P2->next->next;
if(P1==P2)
{
P2 = head;
while(P1!=P2)
{
P1 = P1->next;
P2 = P2->next;
}
return P1;
}
}
return NULL;
}
};