相對簡潔的實現 宣告
文中有些地方並無冒犯之意,希望提及的部落格作者理解。沒有你們的幫助,對這個問題毫無頭緒。
由於csdn部落格系統的內部錯誤,所有的公式後面都有一條惱人的豎線,實屬無奈。
文章梗概
本文通過對現有資料的收集和整理,給出了一種相對簡單的嚴格證明的「判斷單鏈表是否有環,找到環的入口節點」的方法。題目描述
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點(牛客網題目鏈結),題目中沒有說是單鏈表,從給出的**中可以看出是單鏈表而且不可修改鍊錶元素的定義。思考過程
從兩個大的角度思考這個問題
1.記錄遇到的每乙個鍊錶元素
在一次遍歷過程中的,使用一種資料結構(陣列、hash表、基數樹)記錄遇到的每乙個鍊錶元素並判斷是否已經遇到過,其中使用基數樹可以獲得o(2.利用鍊錶的性質 相關問題的解法與證明n)的時間複雜度,但是可會有比較高的空間複雜度。
給定乙個鍊錶,只給出頭指標
h
1.如何判斷是否存在環?
使用追趕的方法,設定兩個指標sl2.如何知道環的長度?ow、f
ast ,均從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fa
st遇到nu
ll退出。
其中主要的思想就是「環形相遇追及問題」,理解上應該不複雜。
記錄下問題1的相遇點,sl3.如何找出環的連線點在**?ow、f
ast 從該點開始,再次相遇時sl
ow所經過的節點數就是環的長度。
從環上的任意一點開始,sl
ow、f
ast 再次相遇時sl
ow經過的節點數就是環的長度,因為此時sl
ow、f
ast 起始距離為環長,速度差為
1 。選擇問題1的相遇點為起始點是為了確保起始點為環上的一點。
設問題1中的相遇點為m1,賦值p=
m1,q=
h ,其中
h 為煉表頭結點,然後p,
q 每次1步向前運動,p,
q 再次相遇所在的位置就是環的入口節點(環的連線點)。
這裡和上面提到的部落格中的敘述差別非常大,這也是其有些問題的地方,我在這裡更正了其說法,並給出了相對嚴格的證明。
public
class solution
if(p == q)
return q;}}
return
null;
}
**及問題三的證明
我們把該鍊錶抽象為這樣乙個模型,假設環長為
n 。
情景1此圖表示其實狀態,其中
h 表示煉表頭節點,sl
ow,f
ast ,起始狀態指向
h ,
t 表示環的入口節點。
情景2此圖表示sl
ow運動到了
t ,fa
st運動到m1
,節點h 和節點
t 之間的距離為
a ,節點
t 和節點m1
之間的距離(弧長)為
b ,並設此時fa
st在環上做了
r 次圓周運動(因為
a 和
n 的長度都不固定,多以fa
st可能已經在環上運動了好多圈了)。相對於sl
ow其運動的距離為:
a 由於fa
st速度是sl
ow的二倍,所以其運動的距離(步數)為:2a
並且,經過觀察可知fa
st運動的距離為:a+
nr+b
,所以可知公式①: a
=nr+
b 情景3.
此時,slo
w,fa
st相遇在節點m2
,也就是**中
10 行判斷成立的地方。其中m2
為相遇點,
b 還是為弧長。由於鍊錶的指標是有方向的,我們約定在環上計算距離的時候按照逆時針計算,也就是說,從
t 到m1
的距離為
b ,從m1
到t的距離為n−
b (其中
n 為環的長度)。
同理在情況2中,從fa
st到slo
w 的距離為n−
b ,它們的速度差為
1 ,所以它們再次相遇的時候經過的時間為n−
b1=n
−b,slo
w 經過的距離為(n
−b)×
1=n−
b ,所以假設相遇點為m2
,那麼顯而m2
到t的距離為
b 。
情景4.
情況4對應著**中的
11 ~
19 行。因為通過上面的討論,如果能讓
q 向前運動:b+
xn步,那麼
q 的位置恰好是
t ,其中x∈
。 值得高興的是,在情況2中我們有公式①,觀察到
a 恰好符合這樣乙個步數值,所以我們讓p=
h ,p,
q ,都每次向前移動
1 ,當他們相遇的時候恰好就是環的入點
t ,也就是說
p 從
h 移動到p,
q 再次相遇在這裡的作用是提供乙個計數。
所以,當
p ,
q 再次相遇的時候,他們的相遇點恰好了
t ,也就是需要找的環的入口點。
複雜度我們關注第一次迴圈的sl
ow和第二次迴圈的
p ,因為它們都是每次前進一步,由它們移動的步數,可以得到演算法的時間複雜度,所以易知時間複雜度為o(
n),空間複雜度為o(1)。
判斷單鏈表中是否有環,找到環的入口節點
相對簡潔的實現 宣告 文中有些地方並無冒犯之意,希望提及的部落格作者理解。沒有你們的幫助,對這個問題毫無頭緒。由於csdn部落格系統的內部錯誤,所有的公式後面都有一條惱人的豎線,實屬無奈。文章梗概 題目描述 乙個鍊錶中包含環,請找出該鍊錶的環的入口結點 牛客網題目鏈結 題目中沒有說是單鏈表,從給出的...
判斷單鏈表中是否有環,找到環的入口節點
相對簡潔的實現 宣告文中有些地方並無冒犯之意,希望提及的部落格作者理解。沒有你們的幫助,對這個問題毫無頭緒。由於csdn部落格系統的內部錯誤,所有的公式後面都有一條惱人的豎線,實屬無奈。文章梗概 題目描述 思考過程 n o n 的時間複雜度,但是可會有比較高的空間複雜度。相關問題的解法與證明 h1....
判斷單鏈表中是否有環
define crt secure no deprecate include include include include define ok 1 define error 0 define true 1 define false 0 typedef int status 函式結果狀態 如ok。t...