一个链表中包含环,请找出该链表的环的入口结点。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
/** 资料快慢指针:http://www.cnblogs.com/hxsyl/p/4395794.html
http://blog.csdn.net/to_be_better/article/details/50871143
判断是否有环就不解释了,下面主要解释,为什么可以那样找环入口。
⬇️<-<-<-⬆️
⬇️ ⬆️
♦️->->->⬇️->->->⬆️
A B C
只是个简单图,就不专门做图了,凑合表示下吧。
♦️也就是A的位置是头节点,B表示环入口处,C表示快慢指针第一次相遇处。
在C处相遇时,设慢指针跑了N步,也就是从A开始N步后会到达C。
快指针比慢指针走的快一倍,也就是走了2*N步。那么慢指针从C处再跑N步还会回到C处。
既然都会回到C处,那么必然会在B点第一次相遇。
所以我们在入口处再设一指针(用之前快指针即可),与慢指针用1步长同时前进,第一次相遇处就是环入口处。
运动是相对的,快指针相对于慢指针,就相当于慢指针静止,快指针每次移动一步。这样只要是在环中,快指针肯定会与慢指针相遇。
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL||pHead->next==NULL)
return NULL;
ListNode *last=pHead;
ListNode *beg=pHead;
while(beg!=NULL&&last->next!=NULL)
{
beg=beg->next;
last=last->next->next;
if(beg==last)
{
last=pHead;
while(last!=beg)
{
last=last->next;
beg=beg->next;
}
if(last==beg)
return last;
}
}
return NULL;
}
};