1. 程式人生 > 其它 >快慢指標判斷連結串列中是否存在環&查詢環的起始位置

快慢指標判斷連結串列中是否存在環&查詢環的起始位置

技術標籤:經典演算法演算法連結串列指標java

判斷連結串列中是否有環?
使用快慢指標, 慢指標一次走一步, 快指標一次走兩步, 當快慢指標相遇時,說明連結串列存在環
為什麼快指標每次走兩步而慢指標每次走一步呢?
因為slow指標和fast指標都會進入環內, 就像在環形跑道內不同位置的兩個人;slow指標在後面,
fast指標在前面, 但實際上fast指標也在追slow指標, 希望能在環內超slow指標一圈(當超過一圈時會
相遇)。那麼fast指標總會追上slow指標的;

那麼fast指標會不會跳過slow指標呢(為什麼快慢指標的步驟差必須為1呢)?
不會的, 因為fast每次走2步,slow每次走1步,假設兩者在環內的距離差為N, 那麼每次走動, 距離差N都

會縮小一步, 因為fast與slow指標的步長差是1(1也是fast與slow指標之間距離的最小單位);最終,N會減少到0,
也就是兩者會相遇。如果fast指標每次走兩步,那麼當fast與slow間只剩一步時, fast指標會錯過slow指標;

如何查詢連結串列環的起始位置?

假設slow指標和fast指標從A點出發, 最終在C點相遇, 那麼可以判斷連結串列中存在環; 此時slow指標移動距離為L1+L2,fast指標移動距離為: L1+L2 + L3+L2;

由於fast指標速度是slow指標的2倍, 那麼如果slow指標移動的距離為S, 那fast指標移動的記錄就是2S

, 所以2 * (L1+L2) =L1+L2+L3+L2, 因此可以得出:L1 == L3

那麼如果將fast指標置於C點, slow指標置於A點, 這次以相同的速度移動, 當兩個指標再次相遇時, 就是環的起始位置B點

  • 虛擬碼:

fast = head
slow = head //快慢指標都指向頭部
do {
  快指標向後兩步
  慢指標向後一步
} while 快慢指標不相等時
if 指標都為空時{
  return null // 沒有環
}
while 快慢指標不相等時{
  快指標向後一步
  慢指標向後一步
}
return fast