快慢指標判斷連結串列中是否存在環&查詢環的起始位置
阿新 • • 發佈:2021-02-14
判斷連結串列中是否有環?
使用快慢指標, 慢指標一次走一步, 快指標一次走兩步, 當快慢指標相遇時,說明連結串列存在環
為什麼快指標每次走兩步而慢指標每次走一步呢?
因為slow指標和fast指標都會進入環內, 就像在環形跑道內不同位置的兩個人;slow指標在後面,
fast指標在前面, 但實際上fast指標也在追slow指標, 希望能在環內超slow指標一圈(當超過一圈時會
相遇)。那麼fast指標總會追上slow指標的;
那麼fast指標會不會跳過slow指標呢(為什麼快慢指標的步驟差必須為1呢)?
不會的, 因為fast每次走2步,slow每次走1步,假設兩者在環內的距離差為N, 那麼每次走動, 距離差N都
也就是兩者會相遇。如果fast指標每次走兩步,那麼當fast與slow間只剩一步時, fast指標會錯過slow指標;
如何查詢連結串列環的起始位置?
假設slow指標和fast指標從A點出發, 最終在C點相遇, 那麼可以判斷連結串列中存在環; 此時slow指標移動距離為L1+L2,fast指標移動距離為: L1+L2 + L3+L2;
由於fast指標速度是slow指標的2倍, 那麼如果slow指標移動的距離為S, 那fast指標移動的記錄就是2S
那麼如果將fast指標置於C點, slow指標置於A點, 這次以相同的速度移動, 當兩個指標再次相遇時, 就是環的起始位置B點
-
虛擬碼:
fast = head
slow = head //快慢指標都指向頭部
do {
快指標向後兩步
慢指標向後一步
} while 快慢指標不相等時
if 指標都為空時{
return null // 沒有環
}
while 快慢指標不相等時{
快指標向後一步
慢指標向後一步
}
return fast