給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。
遍歷鍊錶,將訪問的節點進行標記,如果出現訪問到該節點時該節點曾經被訪問過,說明該節點就是環的入口節點
/*
struct listnode
};*/
class
solution
return
null;}
};
另外一種方法參考:牛課討論
假設x為環前面的路程(黑色路程),a為環入口到相遇點的路程(藍色路程,假設順時針走), c為環的長度(藍色+橙色路程)
當快慢指標相遇的時候:
此時慢指標走的路程為sslow = x + m * c + a
快指標走的路程為sfast = x + n * c + a
2 sslow = sfast
2 * ( x + m*c + a ) = (x + n *c + a)
從而可以推導出:
x = (n - 2 * m )*c - a
= (n - 2 *m -1 )*c + c - a
即環前面的路程 = 數個環的長度(為可能為0) + c - a
什麼是c - a?這是相遇點後,環後面部分的路程。(橙色路程)
所以,我們可以讓乙個指標從起點a開始走,讓乙個指標從相遇點b開始繼續往後走,
2個指標速度一樣,那麼,當從原點的指標走到環入口點的時候(此時剛好走了x)
從相遇點開始走的那個指標也一定剛好到達環入口點。
所以2者會相遇,且恰好相遇在環的入口點。
最後,判斷是否有環,且找環的演算法複雜度為:
時間複雜度:o(n)
空間複雜度:o(1)
/*
struct listnode
};*/
class
solution
else
return
null;}
//程式執行到這裡說明鍊錶中有環
fast=phead;
while
(fast!=slow)
return slow;}}
;
劍指offer解法
基本思想:
分析:上述思想有點類似於求鍊錶中的倒數第k個節點
/*
struct listnode
};*/
class
solution
else
return
null;if
(fast-
>next)
fast = fast-
>next;
else
return
null;}
listnode *meet = fast;
//相遇節點
//2.環中有幾個節點
int m =0;
dowhile
(fast != slow)
;//3.尋找相遇節點
slow = phead;
fast = phead;
while
(m--
)while
(slow != fast)
return fast;}}
;
劍指offer23 鍊錶中環的入口節點
給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。兩個指標,p1,p2 p1一次走一步,p2一次走兩步。第一次相遇之後開始計數,第二次再相遇時count的值就是環有多少個節點。兩個指標,p1,p2 p1先走count步,然後兩個再同時走,相遇的點就是入口節點。struct l...
劍指offer23 鍊錶中環的入口節點
判斷單鏈表中有沒有環,如果有找到環的入口節點。三個問題 1 如何確定鍊錶中包含環 兩個指標,乙個指標一次走一步,乙個指標一次走兩步。如果走得快的指標追上了走得慢的指標,則說明鍊錶包含環 如果走得快的指標走到了鍊錶末尾 p next null 都沒有追上第乙個指標,則無環。2 如何找到環的入口 定義兩...
劍指offer 23 鍊錶中環的入口節點
給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出none。思路 1.找相遇點 設定乙個快指標pfast乙個慢指標pslow,先找到乙個相遇點,一定在環中 2.計算環的長度 從相遇點出發,到相遇點結束 1,即為環的長度。3.pfast 從phead 環的長度出發 pslow從phead...