力扣學習筆記:142. 環形連結串列 II

和BUG做朋友的zhj 發表於 2020-10-17

題目:142.環形連結串列II
建議:先看環形連結串列Ⅰ

演算法
雜湊表

  • 和 Ⅰ類似,只是在碰到前面遇到過的結點,就返回該結點的地址即可

快慢指標

  • 我們將入環結點之前的結點距離設為 a ,將在環上快慢指標相遇的結點逆時針到入環結點的距離設為 b ,將在環上快慢指標相遇的結點順時針到入環結點的距離設為 c 。
  • 我們可以計算 a + n * c + (n + 1) * b = 2 * ( a + b) (快指標的速度是慢指標的兩倍)
  • 化簡得 a = c + (n - 1) * ( b + c)
  • 這樣子,我們知道,a 等於 c 加上 (n - 1)圈
  • 我們可以設一個ptr指標指到起點,讓它和慢指標一起出發,最終會在入環結點碰頭,返回地址即可

原始碼

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
         if(head == nullptr){
            return nullptr;
        }
        ListNode* fast;
        ListNode* low;
        ListNode* ptr;

        fast = head;
        low = head;
        ptr = head;

        while(fast != nullptr && fast->next != nullptr && low != nullptr){
            fast = fast->next->next;
            low = low->next;
            if(fast == low){
                while(ptr != low){
                    ptr = ptr->next;
                    low = low->next;
                }
                return ptr;
            }
        }
        return nullptr;
    }
};