鏈表中環的入口結點

題目:
一個鏈表中包含環,請找出該鏈表的環的入口結點。

解法一:

定義指針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;
    }
};

解法二:

  1. 找到環中相遇點。分別用p1,p2指向鏈表頭結點,p1每次走一步,p2每次走2步,直到p1==p2找到環中相遇點。
  2. 找環入口。假設起點到相遇點距離爲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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章