劍指offer:鏈表中的環入口

給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出null。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
// 首先判斷是否包含環,如果包含環,則統計環中節點的個數
//     1.使用兩個指針,一個走兩步,一個走一步,則一定能在環中相遇
//     2.相遇後一個節點不動,另一個節點每次走一步統計環中節點的個數
// 根據統計的個數n,使用兩個指針,其中一個指針先走n步,兩個指針相遇處就是環的入口處
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
          int num = 0;
          if(pHead == NULL) return NULL;
          ListNode* p1 = pHead;
          ListNode* p2 = pHead;
          bool has = false;
          if(p1->next == NULL) return NULL; //只含有一個節點
          p2 = p1->next ->next;
          while(p1 != NULL && p2!=NULL && p2->next!=NULL) { //判斷是否存在環
                  if(p1 == p2) { // 說明存在環
                      has = true;
                      break;
                  } else {
                     p1 = p1->next;
                     p2 = p2->next->next;
                  }
          }
         if(has) {  // 統計環中節點的個數
             while(1) {
                p1 = p1->next;
                num++;
                if(p1 == p2) break;
             }
         } else return NULL;
          p1 = pHead;
          p2 = pHead;
          
          while(num > 0){  //提前走n步
               num--;
               p2 = p2->next;
            }
           while(p2!=p1){ // 一起往前走
              p1 = p1->next;
              p2 = p2->next;
           }
        return p1; // 返回環入口
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章