此问题包含两个步骤:
(1)判断链表中是否有环
(2)找出环
一、
选择快慢指针,让快指针每次走两步,慢指针每次走一步,若是单链表中有环的话,那么两个指针会相遇,此时可返回其在环中的相遇点。
二、
1)当相遇的时候,设慢指针在环中走了k步,设环之外的部分长为x,环的长度为c,则快指针一共走了 x+m1*c+k
步,(m1为快指针在环中走的圈数),慢指针一共走了x+m2*c+k
(m2为快指针在环中走的圈数)步,因为快指针的速度是慢指针的两倍。那么可以得到2(x+m2*c+k)= x+m1*c+k
;得到x为m*c-k ,慢指针在圈中还剩下的步数c-k;
2)让快指针从头开始,两个指针每次都走一步,当快指针走了x+(m*c-k)步的时候,到达环的入口,慢指针在圈中走m-1圈加k步的时候,也到达环入口那个节点,两个指针再次相遇,此刻的节点就是环的入口的节点。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
//判断是否带环
ListNode *fast=pHead,*slow=pHead;
while(fast && fast->next){
fast=fast->next->next;
slow=slow->next;
//带环,返回交点
if(fast==slow)
break;
}
fast=pHead;
if(fast==NULL || fast->next==NULL)
return NULL;
while(fast!=slow){
fast=fast->next;
slow=slow->next;
}
return slow;
}
};