文章出處

題目描述

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

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {

    }
};

題目鏈接

粗暴方法,供出利器map:
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead == NULL)
            return NULL;
        map<ListNode*, int> cnt;
        while(pHead != NULL)
        {
            cnt[pHead]++;
            if(cnt[pHead] == 2)
                return pHead; 
            
            pHead = pHead->next; 
        }
        
        return NULL; 
    }
};




燒腦解法:
  • 第一步: 找環中相匯點。分別用p1,p2指向鏈表頭部,p1每次走一步,p2每次走二步,直到p1==p2找到在環中的相匯點。
  • 第二步: 找環的入口。接上步,當p1==p2時,p2所經過節點數為2x, p1所經過節點數為x,設環中有r個節點, p2比p1多走 n (n >= 1)圈. 有2x=nr+x; 可以看出p1實際走了n個環的步數,再讓p2指向鏈表頭部,p1位置不變,p1,p2每次走一步直到p1==p2; 此時p1和 p2指向環的入口.
簡單證明:

設起點到相遇點距離為x,起點到入口點距離為y,環長度為r, 則快慢指針相遇時,滿足2x-x=nr,n為快指針在環中轉的圈數。于是 x=nr 快慢指針相遇點距環入口點距離 x-y(正負沒關系) 。相遇后,快指針從起點重新開始以步長為1速度開始走,經過距離y到達環入口點,慢指針走y步后距離環入口點距離為 x-y+y = x = nr,即走到了環入口點,兩個指針相遇!

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead == NULL)
            return NULL; 
        ListNode* fastPos = pHead; 
        ListNode* slowPos = pHead;
        while(fastPos != NULL && slowPos != NULL)
        {
            if(fastPos->next != NULL)
            {
                fastPos = fastPos->next; 
                fastPos = fastPos->next; 
            }
            else
                return NULL; 
            
            slowPos = slowPos->next; 
            
            if(slowPos == fastPos)
                break;
        }
        
        if(fastPos == NULL || slowPos == NULL)
            return NULL;
        
        fastPos = pHead; 
        while(fastPos != slowPos)
        {
            fastPos = fastPos->next; 
            slowPos = slowPos->next; 
        }
        
        return fastPos; 
    }
};





文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()