鏈表常用套路之——快慢指針


鏈表問題常用套路之——快慢指針

概述

使用多個指針是解決鏈表問題的常用套路(諸如反轉鏈表需要三個指針前中后等),其中有兩個比較特殊的指針分別是slow指針和fast指針,也叫快慢指針。

原理

快慢指針顧名思義,即一個移動的比較快的指針和一個移動的比較慢的指針。

實際運用中可以這么寫:

slow = slow.next;
fast = fast.next.next;

假設快慢指針原來都指向頭結點,這樣的話,fast指針移動速度就是slow指針的兩倍,這是很有用的設計。

用途

舉兩個例子來說明快慢指針的用途.

1.找到鏈表中點

快慢指針可以很快的找到鏈表的中點。在不知道鏈表長度的情況下,找到鏈表的中點,一個比較慢的方法是下面這樣做。

int length = 0;
ListNode node = head;
// 遍歷一遍鏈表得到鏈表長度
while(node!=null){
    node = node.next;
    length ++;
}
// 根據得到的鏈表長度,可以遍歷長度/2次來找到終點
ListNode centerNode = head;
for(int i=0;i<length/2-1;i++){
    centerNode = centerNode.next;
}

上面的方法遍歷了N+N/2次,且代碼略顯復雜,最后遍歷長度/2次時,要注意centerNode節點實際上是中點的下一個節點,所以可以讓遍歷次數-1來得到中點.

下面是使用了快慢節點的做法:

// 快慢指針起點相同
ListNode slow = head;
ListNode fast = head;
while(fast.next!=null && fast.next.next!=null){
    slow = slow.next;
    // 快指針移動速度為慢指針兩倍
    fast = fast.next.next;
}
// 當快指針到達鏈表表尾時,此時慢指針指向鏈表中點
ListNode centerNode = slow;

可以看到,上述代碼僅遍歷N/2此就找到了鏈表的中點.

例題:

判斷回文鏈表:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/6/linked-list/45/

問題要求O(N)時間復雜度與O(1)空間復雜度,思路是:

1. 找到鏈表中點
2. 根據中點將鏈表掰成前后兩段
3. 對鏈表后段進行翻轉
4. 根據鏈表前段和經過翻轉后的后段來判斷回文

找中點的過程即可以使用快慢指針來查找.

2.鏈表判環

判斷一個鏈表中是否有環,使用快慢指針思路會非常簡單.

簡單來說,就是,讓快慢指針起點相同,快指針移動速度是慢指針兩倍,當快指針與慢指針相遇的時候說明此鏈表有環,否則沒環.

例題:

環形鏈表:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/6/linked-list/46/


免責聲明!

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



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