Leetcode142 環形鍊錶

2021-10-24 15:02:58 字數 3488 閱讀 8218

目錄

一、題目

二、示例

三、思路

四、**

給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。 如果鍊錶無環,則返回 null。

為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鍊錶中沒有環。

說明:不允許修改給定的鍊錶。

高階:

你能用 o(1)(即,常量)記憶體解決此問題嗎?

示例1:

輸入:head = [3,2,0,-4], pos = 1

輸出:tail connects to node index 1

解釋:鍊錶中有乙個環,其尾部連線到第二個節點。

示例2:

輸入:head = [1,2], pos = 0

輸出:tail connects to node index 0

解釋:鍊錶中有乙個環,其尾部連線到第乙個節點。

示例3:

輸入:head = [1], pos = -1

輸出:no cycle

解釋:鍊錶中沒有環。

1、雜湊表:遍歷所有的節點,每次遍歷乙個節點時,判斷該節點之前是否被遍歷過。

複雜度:時間複雜度:o(n)

空間複雜度:o(n)

2、(高階)快慢指標:

首先,定義兩個指標,快指標fast,慢指標slow,fast指標每次移動兩個節點,slow指標每次移動乙個節點。如果量兩指標在移動過程中相遇,則鍊錶有環,否則,無環。

那麼其中的原理是什麼呢?

第一種情況,鍊錶無環,那麼fast指標一定先比slow指標移動到鍊錶尾部,並且fast指標始終在slow指標前面(除始發位置),因此兩指標一定不會相遇;

第二種情況,鍊錶有環。正如龜兔賽跑一樣,假想「烏龜」和「兔子」在鍊錶上移動,「兔子」跑得快,「烏龜」跑得慢。那麼「兔子」會先於「烏龜」進入環,並且一直在環內移動。等到「烏龜」進入環時,由於「兔子」的速度快,它一定會在某個時刻與烏龜相遇,即套了「烏龜」若干圈。

如下圖所示,設煉表中環外部分的長度為 a。slow 指標進入環後,又走了 b 的距離與 fast 相遇。

此時,fast 指標已經走完了環的 n 圈,因此fast走過的總距離為 a+n(b+c)+b;slow指標走過的距離總距離為 a + b。

又因為fast指標所走的距離是slow指標的2倍,因此得到以下公式:

a+n(b+c)+b = 2(a + b)

得:a=c+(n−1)(b+c) 其中n為走過的圈數,未知數

我們會發現:從相遇點到入環點的距離加上 n-1n−1 圈的環長,恰好等於從鍊錶頭部到入環點的距離。

因此,當發現 slow 與 fast 相遇時,我們再額外使用乙個指標 q。起始,它指向鍊錶頭部;隨後,q和slow 每次向後移動乙個位置。最終,它們會在入環點相遇。

複雜度:時間複雜度:o(n)

空間複雜度:o(1)

1、

# definition for singly-linked list.

class listnode:

def __init__(self, x):

self.val = x

self.next = none

class solution:

def detectcycle(self, head: listnode) -> listnode:

s = set()

while(head):

if head in s:

return head

else:

s.add(head)

head = head.next

if __name__ == '__main__':

head = listnode(3)

head.next = listnode(2)

head.next.next = listnode(0)

head.next.next.next = listnode(4)

head.next.next.next.next = head.next

s = solution()

ans = s.detectcycle(head)

print(ans)

2、

# definition for singly-linked list.

class listnode:

def __init__(self, x):

self.val = x

self.next = none

class solution:

def detectcycle(self, head: listnode):

fast, slow = head, head

while fast and fast.next:

fast = fast.next.next

slow = slow.next

if fast == slow:

q = head

while q != slow:

q = q.next

slow = slow.next

return q

return none

if __name__ == '__main__':

head = listnode(3)

head.next = listnode(2)

head.next.next = listnode(0)

head.next.next.next = listnode(4)

head.next.next.next.next = head.next

s = solution()

ans = s.detectcycle(head)

print(ans)

leetcode 142 環形鍊錶

給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。如果鍊錶無環,則返回null。說明 不允許修改給定的鍊錶。思路 首先通過快慢指標的方法判斷鍊錶是否有環 接下來如果有環,則尋找入環的第乙個節點。具體的方法為,首先假定鍊錶起點到入環的第乙個節點a的長度為a 未知 到快慢指標相遇的節點b的長度為 a b 這個...

leetcode 142環形鍊錶

給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。如果鍊錶無環,則返回 null。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。說明 不允許修改給定的鍊錶。example 輸入 head 3,2,0,4 pos 1...

Leetcode 142 環形鍊錶

問題重述 給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。如果鍊錶無環,則返回 null。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。注意,pos 僅僅是用於標識環的情況,並不會作為引數傳遞到函式中。說明 不允...