檢測單鏈表是否有環

2021-09-12 09:37:09 字數 2271 閱讀 3606

參考:判斷乙個單鏈表是否有環及環的鏈結點***

給定乙個單鏈表,只給出頭指標h:

1、如何判斷是否存在環?

2、如何知道環的長度?

3、如何找出環的連線點在**?

4、帶環鍊錶的長度是多少?

解法:

1、對於問題1,使用追趕的方法,設定兩個指標slow、fast,從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到null退出。

2、對於問題2,記錄下問題1的碰撞點p,slow、fast從該點開始,再次碰撞所走過的運算元就是環的長度s。

3、問題3:有定理:碰撞點p到連線點的距離=頭指標到連線點的距離,因此,分別從碰撞點、頭指標開始走,相遇的那個點就是連線點。(證明在後面附註)

附加:如果每個節點的元素值不重複,所有節點的元素值排序,第乙個重複出現的節點就是。

4、問題3中已經求出連線點距離頭指標的長度,加上問題2中求出的環的長度,二者之和就是帶環單鏈表的長度

參考:求有環單鏈表中的環長、環起點、鍊錶長

1.判斷單鏈表是否有環

使用兩個slow, fast指標從頭開始掃瞄鍊錶。指標slow 每次走1步,指標fast每次走2步。如果存在環,則指標slow、fast會相遇;如果不存在環,指標fast遇到null退出。

就是所謂的追擊相遇問題:

2.求有環單鏈表的環長

在環上相遇後,記錄第一次相遇點為pos,之後指標slow繼續每次走1步,fast每次走2步。在下次相遇的時候fast比slow正好又多走了一圈,也就是多走的距離等於環長。

設從第一次相遇到第二次相遇,設slow走了len步,則fast走了2*len步,相遇時多走了一圈:

環長=2*len-len。

3.求有環單鏈表的環連線點位置

第一次碰撞點pos到連線點join的距離=頭指標到連線點join的距離,因此,分別從第一次碰撞點pos、頭指標head開始走,相遇的那個點就是連線點。

在環上相遇後,記錄第一次相遇點為pos,連線點為join,假設頭結點到連線點的長度為lena,連線點到第一次相遇點的長度為x,環長為r

第一次相遇時,slow走的長度 s =lena+x;

第一次相遇時,fast走的長度 2s =lena+ n*r+x;

所以可以知道,lena+x =n*r;lena = n*r -x;   (理解:lena = n*(r-1) 【保證回到pos】 + n-x【保證剩下的距離正好到達join】)

4.求有環單鏈表的鍊錶長

上述2中求出了環的長度;3中求出了連線點的位置,就可以求出頭結點到連線點的長度。兩者相加就是鍊錶的長度。

對快慢指標的理解:如果沒有環,快指標一定先走完,兩個指標不會相遇;如果有環,那麼最多只有乙個環,並且兩個指標遲早都會進入環,假定環的長度為l,當慢指標進入環之後,快指標每次能向前追一步距離,最多只要l-1步就能追上慢指標所以可以用兩個指標是否相遇來判斷是否有環。

參考:單鏈表反轉

演算法面試題(1) - 有環鏈表

單鏈表的翻轉是一道很基本的演算法題。

方法1:將單鏈表儲存為陣列,然後按照陣列的索引逆序進行反轉。

方法3:從第2個節點到第n個節點,依次逐節點插入到第1個節點(head節點)之後,最後將第乙個節點挪到新錶的表尾。

檢測單鏈表是否有環新解

檢測單鏈表是否有環有好幾種方法。昨天真正把這個問題想了一下,琢磨小問題有時候還是挺有意思的,從上面的方法來看最簡單最好用的當然就是第二個增加變數,這個可以很好的檢測出環和節點。又好好想想此時的flag只是當作乙個標誌,只需要乙個bool變數或者一位就可以,想到只要一位就很好辦,難道就沒有一位是永遠空...

判斷單鏈表是否有環

1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。當然,fas...

判斷單鏈表是否有環

鍊錶結構 struct list 1 判斷單鏈表是否有環 採用追趕法,設定兩個指標p和q,從煉表表頭開始,p每一步走兩個節點,q每一步走乙個節點,如果鍊錶有環則p和q必相遇。如下 判斷鍊錶是否有環,時間複雜度o n 空間複雜度o 1 list hasloopinlist list head else...