↓快轉到主要內容
  1. LeetCode/

LeetCode 142: Linked List Cycle II

·1 分鐘· ·
LeetCode Medium Hash-Table Linked-List Two-Pointers Floyds-Cycle-Finding-Algorithm
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-11-14

  • 提交紀錄:Accepted ×2

解題思路
#

先用快慢指針找到相遇點(Linked List 模板三)。設頭到入口距離 a、入口到相遇點 b、環長 c:慢的走了 a + b、快的走了兩倍,多走的 a + b 是環長的整數倍,所以 a = k·c - b。

也就是從相遇點再走 a 步會回到入口。讓一個指標回到 head,兩個都一次一步,會同時到達入口。

我的解法
#

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        slow = fast = head
        while fast and fast.next:
            slow, fast = slow.next, fast.next.next
            if slow is fast:
                slow = head
                while slow is not fast:
                    slow, fast = slow.next, fast.next
                return slow
        return None

複雜度
#

時間 O(n),空間 O(1)。

要特別避免的錯誤
#

  • 第二階段兩個指標都一次一步。
  • 也可以用集合記走過的節點,但那是 O(n) 空間。

面試口說整理
#

先用快慢指針找到相遇點;推導可知從頭到入口的距離,等於從相遇點繼續走到入口的距離(模環長),所以讓一個指標回到頭,兩個一起一次一步,再相遇的就是入口。時間 O(n)、空間 O(1)。

相關文章

LeetCode 141: Linked List Cycle
·1 分鐘
LeetCode Easy Hash-Table Linked-List Two-Pointers Floyds-Cycle-Finding-Algorithm
LeetCode 141 解題筆記:Floyd 判圈,快指針一次兩步、慢指針一次一步,有環就一定會相遇;兩個都要從自己的位置往前走
LeetCode 61: Rotate List
·1 分鐘
LeetCode Medium Linked-List Two-Pointers
LeetCode 61 解題筆記:先算長度並接成環,k %= n,從頭走 n - k - 1 步找到新的尾巴再斷開
LeetCode 138: Copy List with Random Pointer
·1 分鐘
LeetCode Medium Hash-Table Linked-List
LeetCode 138 解題筆記:第一次走過建立舊節點到新節點的字典,第二次接上 next 和 random;字典裡先放 None -> None
LeetCode 143: Reorder List
·1 分鐘
LeetCode Medium Linked-List Two-Pointers Stack Recursion
LeetCode 143 解題筆記:找中點、反轉後半段、兩條交錯合併;前半段的尾巴要切斷
LeetCode 82: Remove Duplicates from Sorted List II
·1 分鐘
LeetCode Medium Linked-List Two-Pointers
LeetCode 82 解題筆記:重複的值要全部刪掉,頭也可能被刪,所以用 dummy;發現重複就一路跳到不同的值,再讓 prev.next 接過去
LeetCode 86: Partition List
·1 分鐘
LeetCode Medium Linked-List Two-Pointers
LeetCode 86 解題筆記:兩個 dummy 分別接小於 x 和大於等於 x 的節點,最後接起來,第二段的尾巴設成 None