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

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

 我們直接來看圖。

環路檢測及入口定位原理分析圖

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

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

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

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

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

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

假設相遇時,快指針繞環跑了m圈,則快指針所跑路程爲x+y+m*c;慢指針繞環跑了n圈,則慢指針所跑路程爲x+y+n*c。因爲快指針速度爲慢指針兩倍,則相遇時快指針所跑路程亦爲慢指針兩倍,即2(x+y+n*c) = x+y+m*c

等式推導如下:

2(x+y+n*c) = x+y+m*c

2x+2y+2n*c = x+y+m*c

x = (m-2n)*c-y

x=(m-2n-1)*c+c-y

z=c-y(由圖得知)

x=(m-2n-1)*c+z

由推導結果可知,起點至環入口的距離x爲環周長c的(m-2n-1)倍再加快慢指針相遇點至環入口點的距離z。

在起點處和快慢指針相遇點處分別設置指針p1,p2,兩指針速度一致,當p1走了(m-2n-1)*c的距離時,p1所處位置距離環入口點的距離爲z。此時,p2同樣走了跟p1一樣的距離(m-2n-1)*c,即繞着環走了(m-2n-1)圈。

我們知道p2的出發點正好是快慢指針的相遇點,即便繞着環走了(m-2n-1)圈後,p2所處位置還是在快慢指針相遇點。因此,p2和環入口點的距離爲z。

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

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

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

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

已知 n>=0

已知 m>n

得 m>0,即m>=1

m=1,n=0 帶入等式 x=(m-2n-1)*c+z

x>=0*c+z,即x>=z

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

希望看完這篇文章的讀者朋友們能夠恍然大悟,掌握鏈表環問題的核心原理。如有不懂的地方,歡迎評論區留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章