1. 程式人生 > >Leetcode 142:環形連結串列 II(最詳細的解法!!!)

Leetcode 142:環形連結串列 II(最詳細的解法!!!)

給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null

**說明:**不允許修改給定的連結串列。

進階:
你是否可以不用額外空間解決此題?

解題思路

這是之前問題Leetcode 141:環形連結串列(最詳細的解法!!!)的提高,我們還是採用快慢指標來做。

我們建立兩個指標,一個slow一個fast,我們令移動速度關係為 V f

a s t = 2 V s l
o w
V_{fast}=2*V_{slow} ,我們假設環的長度為 V s l
o w t i m e V_{slow}*time
的倍數k,如果此時slowfast都在環內的話,那麼在一定時間內兩者必定可以相遇(使用相對速度很好理解)。如果此時slow的起點是在環的初始點(例如前面例子中的3),那麼fastslow最後一定會在起點相遇(因為 V s l o w t i m e k % V s l o w V_{slow}*time*k\%V_{slow} 一定為0,其中後面的 V s l o w V_{slow} 為相對速度)。我們現在的問題就變成了如何判斷slow在環的初始點,這也非常簡單,我們再簡歷一個entry指標,當slow==fast的時候,我們判斷slow==entry,如果是的話,那麼entry即為環的初始點,否則的話我們將entry++;slow++;,判斷下一個位置是不是環的起始點。

class Solution:
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head == None:
            return None

        fast, slow, entry = head, head, head
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                while slow != entry:
                    slow = slow.next
                    entry = entry.next

                return entry
        return None

我將該問題的其他語言版本新增到了我的GitHub Leetcode

如有問題,希望大家指出!!!