尋找環鏈表入口點 快慢指標數學原理剖析

2021-09-02 09:58:00 字數 1220 閱讀 8259

鍊錶環路檢測及環入口定位是乙個非常經典的演算法問題,它可在死鎖檢測等實際應用場景發揮重要作用。想必大家都知道這個問題應該使用快慢指標去求解,因為它具有最優的時間複雜度o(n)。但是大家可能對快慢指標的數學原理不是很清楚,為啥它能達到最優。詳細讀了這篇文章,大家必定豁然開朗,掌握快慢指標背後的數學原理。

我們直接來看圖。

先講一下鍊錶環路檢測的原理,相比環入口定位,原理比較簡單。

起點設定兩個快慢指標,同時開始往後跑,每跑一次必須檢測快指標是否到達鍊錶末尾(下乙個節點值為null),如果到達鍊錶末尾則證明該煉表無環。如果該鍊錶存在環,則快慢指標總有邂逅(相遇)的那一刻,由此每跑一次,除了檢測快指標是否到達鍊錶末尾,還需檢測快慢指標所在節點是否相同,相同則代表兩指標相遇了,即環存在。為什麼環存在時快慢指標一定會相遇呢,想必不用過多解釋了,舉個簡單生活中例子,兩個人在足球場跑步,同一起點出發,跑的快的人一定會在某一時刻追上跑的慢的人(多跑一圈)。

現在來分析環入口定位的原理。

環入口定位的前提是先找到快慢指標相遇點,即上述所講的鍊錶環檢測操作(注意存在乙個限定條件,快指標的步長必須為2,慢指標步長必須為1)。當找到相遇點後,在起點處和相遇點處分別設定指標p1和p2,步長均為1,它們同時往後跑,當p1,p2相遇時,它們的相遇點便是環入口。

現在來一波數學推理,證明一下上述演算法的正確性。

x為起點至環入口點的距離,y為環入口至快慢指標相遇點的距離,z為快慢指標相遇點至環入口的距離。

假設相遇時,快指標繞環跑了m圈,則快指標所跑路程為

等式推導如下:

由推導結果可知,起點至環入口的距離x為環周長c的

在起點處和快慢指標相遇點處分別設定指標p1,p2,兩指標速度一致,當p1走了

我們知道p2的出發點正好是快慢指標的相遇點,即便繞著環走了

從上述推算,我們已經得知p1和p2距離環入口點的距離相同,均為z。

兩個指標再往後走z的距離,便會相遇,相遇點便恰好是環入口點。

至此,環入口定位的演算法原理講解完畢。

現在來分析一波邊界情況,以此證明上述公司的正確性。慢指標最少需要跑0圈,即進入環後第一次經過相遇點就被快指標追上了,所以n最小值為0。快指標要追上慢指標,至少要比慢指標多跑一圈,根據這些已知條件,可作推理如下:

已知已知得將

得因此,證明出x不可能為負,即起點距離環入口點距離不為負,符合常規事實,演算法嚴謹性得證。

快慢指標尋找單鏈表中間值

fastsearch.cpp 鍊錶快速查詢中間值,快慢指標的方法 include stdafx.h include struct linklist linklist head linklist malloc sizeof linklist 初始化鍊錶 尾插法 void listinitial lin...

判斷單鏈表是否存在環及尋找環的入口點

單鏈表反 下面給出兩種可能的實現。普通版 void reverse node head head next null head pprev 遞迴版 node reverse node pnode,node head node temp reserve pnode next,head 遞迴 temp ...

判斷單鏈表是否存在環及尋找環的入口點

判斷乙個單鏈表是否存在環的解法如下 問題1 快慢指標何時相遇,是否迴轉幾十圈,才相遇呢?證明1 設環長為l,slow指標第一次進入環內,fast指標在前方的a節點處 0 0 x a 2x mod l 0 a x mod l 兩邊同時減去x 就是說a x對l求餘應該是0,即a x 0,l,2l 這一系...