判斷乙個鍊錶是否有環就有點像判斷乙個小數是否為迴圈小數。如:12.3756954756954...迴圈體為756954進入節點為7。如果我們從這個思路來考慮那就走遠了。因為,可能這個迴圈體長度特別長,而這個迴圈體中又可能存在很多小的迴圈體。比如:1.1235353512791235353512791...如果我們把35當做迴圈體那就錯了,迴圈體應該是123535351279。正確的思路應該是參照環形賽道跑步比賽。試想,如果賽道沒有環那麼即使跑無限長的時間。跑得慢的人永遠看不見跑得快的。而如果是環形賽道,只要時間足夠長,跑得快的遲早會追上跑的慢的。
作為單向連表,設兩個指標 fast,slow,假設fast走2步,slow走1步。
那麼
listnode slow = h;
listnode fast = h;
while(fast != null && fast.next != null )
}return false;
如果要知道到底從哪個節點進入迴圈的呢?
假設相遇點到入環點的距離為x,入環段長度為a,環長r,假設相遇時fast已繞環k圈,slow已繞環n圈,(n∈n+,k∈n+且k>=n),如果fast速度是2倍於slow速度。那麼n>1則k必然大於2,也就是說slow在環上每個位置都出現了一次以上了。那麼fast肯定於slow相遇過(如果fast >2slow的情況不確定。)那麼kr+x+a = 2(nr + x + a)此時令n=0,並且k <= 2n所以k=0
整理 r= a + x;也就是說此時碰撞點離入環點還差a,此時如果設新的兩個指標,p,q同樣速度,乙個從起點,乙個從碰撞點走,當他們下次碰撞的時候一定是入環點。
返回的q則是進入迴圈的節
部分有環單向鍊錶判斷環起點問題
方法一 hash listnode detectcycle listnode head return null 方法二 快慢指標 listnode detectcycle listnode head if fast fast next return null slow head while slow...
單向鍊錶判斷是否有環
如何最有效的檢查單向鍊錶中是否包含了環。請避免使用額外的記憶體。先給出答案吧 定義兩個指標。指標a從鍊錶開始處每次向後移動一個節點。指標b從鍊錶開始處每次向後移動兩個節點。問題的關鍵是乙個單項鍊表中只可能有乙個環,並且指標一旦進入環中就無法離開。因此我們可以預期經過一段時間後,a剛好指向環的第乙個節...
判斷單向鍊錶是否有環
若單向鍊錶存在環那麼鍊錶的形態為 有環的鍊錶簡單的遍歷走不到尾 那麼我們怎麼判斷有環呢?環就像是操場的的跑到 那麼運動天賦一向不太好的 我很容易就能想到跑步時容易讓人扣圈 同理 我們可以定義兩個指標讓他們同時指向鍊錶的頭 乙個指標一次走兩步 乙個指標一次走一步 那麼如果鍊錶有環那麼他們一定會在環內的...