簡體   English   中英

如何用循環找到鏈表的循環節點?

[英]How to find loop-node of a linkedlist with a loop?

這個問題與尋找 2 個鏈表的交集有點不同。

考慮一個帶有循環的鏈表: A - B - C - D - E - F - C

如果節點A是函數的輸入,則它應該返回C

由於我不知道如何稱呼C ,因此我使用了問題中所見的術語循環節點C 盡管 O(n 2 ) 項看起來很明顯,但有沒有辦法找到復雜度較低的循環節點?

不允許使用 O(n) 的哈希表/額外空間。

有一個使用兩個指針的簡單方法。第一個指針增加一個,第二個增加慢指針速度的兩倍。

所以你的情況下的鏈表實際上是A->B->C->D->E->F->C意味着 F 再次指向 C.So 方法如下

1.繼續增加兩個pointers直到它們匹配。所以在上面的情況下我們會有這些步驟

慢指針:ABCDE
快速指針:ACECE

所以我們在 E 處停止,這表明存在一個循環。現在我們需要找到循環節點。

現在從 E 將慢指針移動到鏈表的開頭,並創建一個指向 E 並遞增 1 的新指針。這兩個指針相交的點實際上是循環節點。所以在我們的例子中

從頭開始的指針:ABC 新指針:EFC

因此,如您所見,它們在 C 處相遇,我們完成了在鏈表中查找循環節點的工作。

更新:對於這種方法的數學證明,請參考這個精彩的問題,並查看@Jim Lewis 的回答以及答案下方的所有評論。 解釋在循環鏈表中查找循環起始節點是如何工作的?

Floyd 的循環尋找算法是最簡單的 算法,而且通常是“規范答案”,因為這是每個人在大學里學到的東西(也許是因為它簡單、優雅且富有洞察力)。

人們還經常聲稱運行時不可改進,但事實並非如此——大 Oh 可能無法改進,但這只能告訴我們一些關於最壞情況下漸近行為的信息。 Brent 算法在實踐中更快,同時仍然使用恆定的空間量。 還有更多的算法,例如 Gosper's Loop Detection 或 Sedgewick、Szymanski 和 Yao's 算法或k-stacks 算法,它們都使用一定的(低,但理論上是非恆定的)空間量。 實際上,對於鏈表的任何實際實現,空間量仍然是恆定的,因為您的指針將是固定大小的。 例如,對於 32 位指針,Gosper 的循環檢測將使用 33 個字的空間(加上可能額外的幾個,取決於您想要計數的內容)。

Floyd 的算法很好,但不一定是 The Answer (tm) 需要做出選擇和權衡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM