遍歷鍊錶,將遍歷過的結點都放入list中,當遇到重複結點時,說明找到了環的入口
public listnode entrynodeofloop(listnode phead)
else
phead = phead.next;
}return null;
}
空間複雜度o(n),時間複雜度o(n)
假設x為環前面的路程(黑色路程),a為環入口到相遇點的路程(藍色路程,假設順時針走), c為環的長度(藍色+橙色路程)
當快慢指標相遇的時候:
此時慢指標走的路程為x + m * c + a
快指標走的路程為x + n * c + a
(m,n分別為走過環的圈數)
2slow = fast 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)
public class solution
listnode slow = phead.next;
listnode fast = phead.next.next;
while (fast != slow)
//相遇
slow = phead;
while (slow != fast)
return slow;}}
小結:只要存在環,那麼兩個速度不一樣的指標肯定會相遇,所以速度比可以是任意的
從上圖中可以看出,環的入口結點和其他結點的區別:環的入口結點是有兩個指標指向的,其他結點除了頭結點都是只有乙個指標指向的,使用斷鏈法,在當前結點訪問完畢後,斷掉指向當前結點的指標。因此,最後乙個被訪問的結點一定是入口結點。
}參考:
鍊錶中環的入口結點
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。class listnode public class solution return p1 return null 分析 假設鍊錶的起始點到環的入口點節點數為k,環的的節點數為x,讓p2的速度是p1的兩倍,p1和p2相遇在環的第y各節點,可以得到如下等...
鍊錶中環的入口結點
題目要求 乙個鍊錶中包含環,請找出該鍊錶的環的入口結點 分析 1 一種比較偷懶的方法就是遍歷鍊錶,並直接利用hashmap來儲存已經遍歷過的結點。一旦發現已經儲存過的結點,那麼該結點就是環的入口結點。2 參考自 我簡單畫了乙個圖 上傳之後一直是橫過來的。不知道為什麼轉不正 設定兩個指標p1和p2,乙...
鍊錶中環的入口結點
題目描述 乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。思路1 設環中結點數是n,環的入口位置是x 距離起點走多少步 用快慢指標p,q,q移動的速度是p的2倍,當兩個指標相遇時p走的步數是y,q走的步數是2y,q比p多走k個環的距離,即 2y y kn,則y kn。p距離環的入口點的距離為y x,此...