劍指offer_編程題_鏈表中環的入口結點

  • 題目
    給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,
    否則,輸出null。
    
  1. 遍歷鏈表並存儲,若發現一節點已經遍歷過,則該節點爲入口結點
    /*
    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* temp = pHead;
     	   std::map<ListNode*, int> m;
     	   while(temp->next!=NULL)
     	   {
     		   if (m.count(temp)>0)
     			   return temp;
     		   else
     			   m[temp] = 1;
     		   temp = temp->next;
     	   }
     	   return NULL;
        }
    };
    
  2. 遍歷鏈表,並將已遍歷節點的next指向一個自定義的節點
    若即將遍歷的節點指向自定義的節點,則爲入口結點
    /*
    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* mybase = new ListNode(0);
     	   ListNode* temp;
     	   while(pHead->next!=NULL&&pHead->next!=mybase)
     	   {
     		   temp = pHead->next;
     		   pHead->next = mybase;
     		   pHead = temp;
     	   }
     	   if (pHead->next==NULL)
     		   return NULL;
     	   else 
     		   return pHead;
        }
    };
    
  3. 通過兩個指針分別以1的速度、2的速度移動,若存在環,則兩指針必定相遇
    假設存在環,環長爲n,即節點數量爲n,並設入口點爲第一個節點
    當1走到環的第一個節點時,2可能出現在環上的任意一點x(1<=x<=n)
    ①此時,如果2降低速度爲1,那麼2永遠處在1的前方(x-1)個位置
    如果2停下,1需要走(x-1)與2相遇
    也就是說,1如果從開始處出發,2在環的第一個節點處等待(x-1)個時間後以與1相同的速度出發,那麼兩指針會相遇
    ②當1走到環的第一個節點時,如果2仍然以2的速度前進,兩者速度2比1快1,2將會追上1
    環長爲n,2在1的前方(x-1)個位置,2如果要追上1,需要[n-(x-1)]個時間
    即1和2的相遇點爲(1+[n-(x-1)]),相遇點到環的第一個節點的距離爲(n-[(1+[n-(x-1)])-1])=(x-1)
    由①1如果從開始處出發,2在環的第一個節點處等待(x-1)個時間後以與1相同的速度出發,那麼兩指針會在入口處相遇
    所以有1從開始處出發,2從相遇點出發,以同樣的速度1,兩個指針在入口會相遇
    參考
    /*
    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* p1=pHead;
     	   ListNode* p2=pHead;
     	   while(p2!=NULL&&p2->next!=NULL)
     	   {
     		   p1 = p1->next;
     		   p2 = p2->next->next;
     		   if (p1==p2)
     		   {
     			   p1 = pHead;
     			   while(p1!=p2)
     			   {
     				   p1 = p1->next;
     				   p2 = p2->next;
     			   }
     			   return p1;
     		   }
     	   }
     	   return NULL;
        }
    };
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章