快慢指標判斷單向鍊錶環及找環入口的操作與原理

2021-12-29 16:24:17 字數 1018 閱讀 8986

關於快慢指標找環入口的這個問題,之前巴特跟我聊到過,印象比較深,今晚看學長在做的面試題,裡面就出現了這個小知識。

發現有些東西不經意間就會用到,於是便出現此文。以後要努力做到善於總結,樂於總結。

快慢指標,所謂的快慢,就是指指標每次移動的步長,通常使快指標每次向前移動兩步,慢指標每次向前移動一步。

從煉表頭節點開始,快慢指標同時開始移動,快指標每次移動2,慢指標每次移動1,若快指標最終與慢指標相遇,則表示鍊錶有環,否則,則為無環。

有環情況下,快慢指標相遇時,慢指標位置不變,將快指標置回表頭,步長改為每次移1,快慢指標同時開始移動,再次相遇處即為環的入口。

判斷是否有環就不解釋了,下面主要解釋,為什麼可以那樣找環入口。

??->->??->->->??

a b c只是個簡單圖,就不專門做圖了,湊合表示下吧。

??也就是a的位置是頭節點,b表示環入口處,c表示快慢指標第一次相遇處。

在c處相遇時,設慢指標跑了n步,也就是從a開始n步後會到達c。

快指標比慢指標走的快一倍,也就是走了2*n步。那麼慢指標從c處再跑n步還會回到c處。

既然都會回到c處,那麼必然會在b點第一次相遇。

所以我們在入口處再設一指標(用之前快指標即可),與慢指標用1步長同時前進,第一次相遇處就是環入口處。

/* **很簡單 */

list* func(list* head)

if(fast == null)

return true;

fast = head;

while(fast != slow)

return fast;

}譬如,給定一有序鍊錶,求其中位數,因為不知道鍊錶的具體長度,常規做法是先遍歷一次,確定鍊錶的長度,再遍歷到中點,求出中位數。

但其實還有個更巧妙的法子,很方便的求出中位數,就是用快慢指標。

仍然是快指標步長為2,慢指標步長為1,當快指標到達鍊錶尾部的時候,快指標就處於中點位置.(會牽扯到鍊錶總數奇偶的情況,判斷下即可,這裡就不多贅述了)。

快慢指標判斷鍊錶是否有環

關於鍊錶是否有環,其實是一系列問題,主要包括以下幾個 使用快慢指標fast和slow,fast每次走兩步,slow每次走一步,如果有環,肯定會相遇,如果沒有,則指標fast遇到null退出。追及相遇問題。在環上相遇後,記錄第一次相遇點為pos,之後指標slow繼續每次走1步,fast每次走2步。在下...

雙指標(快慢指標)判斷鍊錶是否有環

單鏈表的特點是每個節點知道下乙個節點 如果用乙個指標來判斷是否有環,當沒有環時,指標一直會指到鍊錶的為即指到null,但是當有環時,指標將陷入死迴圈,因為環形鍊錶中沒有null指標作為尾部節點 while head null head head.next return false 找到一種經典解法 ...

使用快慢指標判斷鍊錶是否有環

今天做到leetcode 141 linked list cycle,判斷鍊錶是否存在環,因為看到題目中的val都是整數,所以我是將每個node用1.1作為值去mark了,如果head.next的val是1.1,就說明我指向的下個結點已經走過了,這就是乙個環,如果走到最後head走到none了還沒返...