判斷鍊錶是否有環,如果有,找到環的入口位置

2022-04-28 07:06:11 字數 2629 閱讀 5806

判斷乙個鍊錶是否有環,空間複雜度是o(1)

如果不考慮空間複雜度,可以使用乙個map記錄走過的節點,當遇到第乙個在map中存在的節點時,就說明回到了出發點,即鍊錶有環,同時也找到了環的入口。

不適用額外記憶體空間的技巧是使用快慢指標,即採用兩個指標walker和runner,walker每次移動一步而runner每次移動兩步。當walker和runner第一次相遇時,證明鍊錶有環

以為例,假設環的長度為r,當慢指標walker走到環入口時快指標runner的位置如圖,且二者之間的距離為s。在慢指標進入環後的t時間內,快指標從距離環入口s處走了2t個節點,相當於從環入口走了s+2t個節點。而此時慢指標從環入口走了t個節點。

假設快慢指標一定可以相遇,那麼有s+2t−t=nr,即s+t=nr,如果對於任意的s,r,n,總可以找到乙個t滿足上式,那麼就可以說明快慢指標一定可以相遇,滿足假設(顯然可以找到)

而實際上,由於s所以如果鍊錶中有環,那麼當慢指標進入到環時,在未來的某一時刻,快慢指標一定可以相遇,通過這個也就可以判斷鍊錶是否有環

**如下

如果鍊錶有環,尋找環入口位置

以為例,假設環入口距離煉表頭的長度為l,快慢指標相遇的位置為cross,且該位置距離環入口的長度為s。考慮快慢指標移動的距離,慢指標走了l+s,快指標走了l+s+nr(這是假設相遇之前快指標已經繞環n圈)。由於快指標的速度是慢指標的兩倍,相同時間下快指標走過的路程就是慢指標的兩倍,所以有2(l+s)=l+s+nr,化簡得l+s=nr

n=1時,即快指標在相遇之前多走了一圈,即l+s=r,也就是l=r−s,觀察,l表示從煉表頭到環入口的距離,而r−s表示從cross繼續移動到環入口的距離,既然二者是相等的,那麼如果採用兩個指標,乙個從表頭出發,乙個從cross出發,那麼它們將同時到達環入口。即二者相等時便是環入口節點

n>1時,上式為l=nr−s,ll仍然表示從煉表頭到達環入口的距離,而nr−s可以看成從cross出發移動nr步後再倒退ss步,從cross移動nrnr步後回到cross位置,倒退s步後是環入口,所以也是同時到達環入口。即二者相等時便是環入口節點

所以尋找環入口的方法就是採用兩個指標,乙個從表頭出發,乙個從相遇點出發,一次都只移動一步,當二者相等時便是環入口的位置

**如下

/**

* definition for singly-linked list.

* struct listnode

* };

*/class solution

if(!runner || !runner->next)

return nullptr;

auto headwalker = head;

auto crosswalker = walker;

while(headwalker != crosswalker)

return headwalker;}};

其它的和環有關的題目記得還有

第一種方法是利用上面求出的環入口,再走一圈就可以求出長度,**如下

int cyclelen(listnode* head)

return len;

}

第二種方法是當快慢指標相遇時,繼續移動直到第二次相遇,此時快指標移動的距離正好比慢指標多一圈,**如下

int cyclelen(listnode* head)

int len = 0;

while(runner && runner->next)

return len;

}

from:

如何判斷乙個鍊錶是否有環,如果有環,並找出環的入口

首先如何判斷乙個鍊錶是否有環 設定兩個指標 fast,slow 初始值都指向頭,slow 每次前進一步,fast 每次前進二步,如果鍊錶存在環,則 fast 必定先進入環,而 slow 後進入環,兩個指標必定相遇。當然,fast 先行頭到尾部為 null 則為無環鏈表 程式如下 bool i its...

判斷乙個單鏈表是否有環,如果有,找出環的起始位置

第一種方法是從單鏈表head開始,每遍歷乙個,就把那個node放在hashset裡,走到下乙個的時候,把該node放在hashset裡查詢,如果有相同的,就表示有環,如果走到單鏈表最後乙個node,在hashset裡都沒有重複的node,就表示沒有環。這種方法需要o n 的空間和時間。第二種方法是設...

如何判斷鍊錶是否有環 鍊錶是否有環的判斷

對於鍊錶是否存在環,有三個問題需要考慮 1.是否有環 2.入環節點 3.環的長度 第一種方法快慢指標法,也稱之為龜兔演算法,設定兩個指標,慢指標和快指標。最開始均指向鍊錶的頭節點,之後,快指標每次後移兩個節點,慢指標每次後移乙個節點。1.如果快指標指向空,則鍊錶無環 2.若快指標和慢指標再次指向乙個...