題目:
一個鏈表中包含環,請找出該鏈表的環的入口結點。
解法一:
定義指針P1和P2指向鏈表的頭結點。假設鏈表中的環有n個結點,指針P1先在鏈表走n步,然後兩個指針以相同的速度前進。因爲P1總是比P2多走n個結點,在進入環之後,當兩個指針相遇時,相遇點則爲環的入口結點。
代碼如下:
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode *meet_Node=MeetingNode(pHead);
if(meet_Node==NULL)
return NULL;
int nodesInloop=1;
ListNode *p1=meet_Node;
while(p1->next!=meet_Node)//環的長度
{
p1=p1->next;
++nodesInloop;
}
p1=pHead;
for(int i=0;i<nodesInloop;++i)
{
p1=p1->next;
}
ListNode *p2=pHead;
while(p1!=p2)
{
p1=p1->next;
p2=p2->next;
}
return p1;
}
private:
ListNode *MeetingNode(ListNode *pHead)
{
if(pHead==NULL||pHead->next==NULL)
return NULL;
ListNode *pFast=pHead;
ListNode *pSlow=pHead;
while(pFast!=NULL&&pFast->next!=NULL)
{
pSlow=pSlow->next;
pFast=pFast->next->next;
if(pSlow==pFast)
return pSlow;
}
return NULL;
}
};
解法二:
- 找到環中相遇點。分別用p1,p2指向鏈表頭結點,p1每次走一步,p2每次走2步,直到p1==p2找到環中相遇點。
- 找環入口。假設起點到相遇點距離爲x,起點到環入口點距離爲y,環長度爲r,則當p1==p2時,有2x-x=nr,n爲快指針在環中走的圈數。由上可知,環中相遇點距環入口距離爲x-y,若此時p2從頭結點開始以步長爲1的速度開始走y步之後,剛好到達環入口,此時慢指針距環入口點的距離爲x-y+y=x=nr,即爲環入口點,即兩個指針相遇。
代碼如下:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL||pHead->next==NULL)
return NULL;
ListNode *p1=pHead;
ListNode *p2=pHead;
while(p2!=NULL&&p2->next!=NULL)
{
p1=p1->next;
p2=p2->next->next;
if(p1==p2)
{
p2=pHead;
while(p1!=p2)
{
p1=p1->next;
p2=p2->next;
}
if(p1==p2)
return p1;
}
}
return NULL;
}