1.有乙個單向鍊錶,鍊錶當中有可能出現「環」,就像下圖這樣。如何用程式判斷出這個鍊錶是有環鏈表?
對於判斷有環問題,能判斷後面的節點和前面節點有沒有相等的,這裡相等是指是同乙個物件,也就只能由乙個後繼節點,對於這種情況,我們可以設定兩個節點,都從頭節點開始,乙個節點走兩步,fast .next.next,乙個節點走一步,即slow .next,如果有環,那麼就會有fast==low的情況,也就能判斷出來是否有環。
2.如何知道環的長度?
記錄下問題1的相遇點,slow、fast從該點開始,再次相遇時slow所經過的節點數就是環的長度。從環上的任意一點開始,slow、fast再次相遇時slow經過的節點數就是環的長度,因為此時slow、fast起始距離為環長,速度差為1。選擇問題1的相遇點為起始點是為了確保起始點為環上的一點。
3.如何找出環的連線點在**?
設問題1中的相遇點為m1,賦值p=m1,q=h,其中h為煉表頭結點,然後p,q每次1步向前運動,p,q再次相遇所在的位置就是環的入口節點(環的連線點)。
如圖中所示,設鏈起點到環入口點間的距離為x,環入口點到問題1中fast與slow重合點的距離為y,又設在fast與slow重合時fast已繞環n周(n>0),且此時low移動總長度為s,則fast移動總長度為2s,環的長度為r。則
s + nr = 2s,n>0 ①
s = x + y ②
由①式得 s = nr
代入②式得
nr = x + y
x = nr - y
此時我們就能得出結論了,從重合點和頭節點向下走,兩者相等的時候為入口。
下面給出**:問題是給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。
需要先判斷是否有環,如果有再判斷環的入口結點,沒有就返回null
public class main
}class listnode
}class solution
fast = fast.next.next;
slow = slow.next;
if (fast == slow)
}if (flag == 0)
while (true)
phead = phead.next;
slow = slow.next;}}
}
劍指offer鍊錶 判斷鍊錶是否有環
題目 給定單向鍊錶的頭指標和乙個要刪除的節點的值,定義乙個函式刪除該節點。返回刪除後的鍊錶的頭節點。注意 此題對比原題有改動 示例 1 輸入 head 4,5,1,9 val 5 輸出 4,1,9 解釋 給定你鍊錶中值為 5 的第二個節點,那麼在呼叫了你的函式之後,該鍊錶應變為 4 1 9.示例 2...
牛客 劍指offer 判斷鍊錶是否有環
題目 判斷鍊錶是否有環 思路 雙指標。快指標每次走2步,慢指標每次走一步。如果有環,二者必定相遇 如果沒環,快指標必定率先到達鍊錶尾部。definition for singly linked list.class listnode public class solution listnode lo...
劍指offer 鍊錶環入口結點
struct listnode class solution if flag 1 說明有環 return meet else 給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。因為之前接觸過帶環的鍊錶所以寫這道題的時候直接想到了快慢指標,程式放到牛客網上也是直接通過了,但是在...