基礎算法之快慢指針


快慢指針即使用一快一慢兩個指針,對鏈表進行遍歷。利用兩個指針的速度差,如2倍速-用於求中間指針或循環鏈表;恆定n個差值,用於尋找倒數第n個指針。

1. 環形鏈表

如果快指針到達NULL,說明鏈表以NULL結尾,不存在環。如果快指針追上慢指針,則表示有環。

public boolean hasCycle(ListNode head) {
    if (head == null || head.next == null) {
        return false;
    }
    ListNode slow = head;
    ListNode fast = head.next;
    while (slow != fast) {
        if (fast == null || fast.next == null) {
            return false;
        }
        slow = slow.next;
        fast = fast.next.next;
    }
    return true;
}

2. 找中間值

我們把一個鏈表看成一個跑道,假設a的速度是b的兩倍,那么當a跑完全程后,b剛好跑一半,以此來達到找到中間節點的目的。

publicListNode endOfFirstHalf(ListNode head) {
    ListNode fast = head;
    ListNode slow = head;
    while (fast.next != null && fast.next.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}

3. 刪除倒數第N個節點

快指針先走n步,慢指針開始和快指針同步移動到next,當快指針到達鏈表尾部時,慢指針剛好移動到倒數第n-1個節點。

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode fast = head;
    ListNode slow = head;
    //慢指針比快指針慢N步,那么快指針指向末尾的null時,慢指針剛好指向要刪除結點的前驅結點
    while (fast.next != null) {
        fast = fast.next;
        if (n == 0) {
            slow = slow.next;
        } else {
            n--;
        }
    }
    if (n != 0) { //沒追上,說明刪除的是頭指針
        return head.next;
    } else {
        slow.next = slow.next.next;
    }
    return head;

}

總結

快慢指針在鏈表類的迭代中,時間復雜度是O(n)的量級,是一種能有效控制時間復雜的算法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM