快慢雙指標法
阿新 • • 發佈:2020-09-06
介紹
快慢雙指標是雙指標問題的一種解決方案,主要用於解決連結串列相關的題目,而左右指標那種滑動視窗的演算法主要是用於解決陣列問題
應用
- 快慢雙指標可以用來判定連結串列中是否存在環
一般而言,如果連結串列中存在環路,那麼對於單鏈表的遍歷就會陷入死迴圈,可以使用快慢雙指標去遍歷該連結串列,慢指標一步一步走,快指標一次走兩步;
那麼如果快指標最終走到null節點,那麼就是遍歷完成;
如果存在環路,那麼快慢指標最終一定會相遇,因為快指標始終快於慢指標一倍的距離
boolean hasCycle(ListNode head) { ListNode fast, slow; fast = slow = head; while(fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) return true; } return false; }
- 找到連結串列中環路的起點
當快慢指標第一次相遇的時候,就可以確定連結串列中存在環路,如果讓其中一個節點回到起點再讓快慢指標以同樣速度前進,那麼再次相遇就是環起點
ListNode detectCycle(ListNode head) { ListNode fast, slow; fast = slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) break; } slow = head; while (slow != fast) { fast = fast.next; slow = slow.next; } return slow; }
- 尋找連結串列中點
我們可以讓快指標一次前進兩步,慢指標一次前進一步,當快指標到達連結串列盡頭時,慢指標就處於連結串列的中間位置。
ListNode slow, fast;
slow = fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// slow 就在中間位置
return slow;
當程式結束時,如果連結串列的長度是奇數時,slow 恰巧停在中點位置;如果長度是偶數,slow 最終的位置是中間偏右;可以利用這個方法去進行歸併排序
- 尋找連結串列的倒數第k個節點
讓快指標先走 k 步,然後快慢指標開始同速前進。這樣當快指標走到連結串列末尾 null 時,慢指標所在的位置就是倒數第 k 個連結串列節點(假設 k 不會超過連結串列長度)
ListNode slow, fast;
slow = fast = head;
while (k-- > 0)
fast = fast.next;
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
return slow;