题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null
思路:把链表里的环看做一条跑道,两个人在匀速跑步,那么跑的快的那个必然在某一刻会“套圈”。
所以,设置两个指针pSlow和pFast,pSlow一次下一个节点,pFast一次下两个节点。如果有环,他俩必然在环中相遇。
所以接下的问题就是怎么把环的入口给弄出来,思路如下:
注:假设是逆时针。
所以 相遇点到入口的距离(L3)与起点到入口的距离(L1)相同,所以我们只要把跑到快的那个人放回起点,并使他的速度变得和那个慢的一样,他俩便可以在入口相遇。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
//节点数目不足以形成一个环,直接返回NULL
if(pHead==NULL|| pHead->next==NULL|| pHead->next->next==NULL)
return NULL;
ListNode* pFast = pHead;
ListNode* pSlow = pHead;
//先走一步,防止把起点误判成公共点
pSlow = pSlow->next;
pFast = pFast->next->next;
while(pSlow!=pFast)
{
if(pFast==NULL||pSlow==NULL)//只要其中一个到尾了,就说明没有,直接return结束循环
return NULL;
pSlow = pSlow->next;
pFast = pFast->next->next;
}
//出来了,说明找到公共节点了
pFast = pHead;//把pFast放回原处
while(pFast != pSlow)
{
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
};