1. 程式人生 > 實用技巧 >單鏈表尋找環的入口

單鏈表尋找環的入口

思路:
使用兩個快慢指標 slow 和 fast 來做:

  • slow 每次走一步,fast 每次走兩步,如果 slow == fast,則說明 slow 和 fast 在環中相遇;
  • 將 fast 放回連結串列頭(fast = head),然後 slow 和 fast 每次都走一步,當 slow 和 fast
    相等時,說明此時 slow 或者 fast 就是連結串列環的入口節點。

第一個比較好理解,第二個可以這麼理解:
在這裡插入圖片描述

假設頭節點到環入口節點的距離為 x,環入口節點到 slow 和 fast 相遇點的距離為 y,slow 和 fast 相遇點到環入口節點的距離為 z,則 slow 走的路程為 x + y,而 fast 走的路程為 x + y + n(y + z)也就是 fast 在環中繞了 n 圈後才與 slow 相遇(n≥0)。因為 fast 每次走 2 步,slow 每次走 1 步,所以相遇時 fast 走的路程是 slow 的兩倍,也就是

2 ( x + y ) = x + y + n ( y + z ) 2(x+y)=x+y+n(y+z) 2(x+y)=x+y+n(y+z)
整理可得
x = ( n − 1 ) ( y + z ) + z x=(n-1)(y+z)+z x=(n1)(y+z)+z
有兩種情況:

  • n=1 時,x=z,此時我們將 fast 放到連結串列頭,然後 fast 和 slow 每次走一步,相遇節點就是環的入口;
  • n>1 時,我們將 fast 放到連結串列頭,當 fast 和 slow 相遇時,說明 slow 在環裡轉了 n-1 圈後又走了z步,等價於 n=1 的情況。