Linked List 題目讓很多人頭痛,不是因為邏輯複雜,而是因為同時在腦海中追蹤多個 pointer 的位置很容易搞亂。這篇用圖示化的方式,把 Reverse、Merge、Cycle 三個核心題的 pointer 操作說清楚。
Linked List 的結構
Linked List 的每個節點(Node)包含兩樣東西:值(val)和指向下一個節點的 pointer(next)。
head(第一個 node 的 pointer)。操作 Linked List 的核心:改變 .next 的指向,而不是移動資料本身。#206 Reverse Linked List
把 1 → 2 → 3 → 4 → None 變成 4 → 3 → 2 → 1 → None。
需要三個 pointer:prev(前一個)、curr(當前)、next_node(暫存下一個,避免斷鏈)。
指針移動過程(1→2→3→None):
也可以用遞迴解,但 iterative 版本的空間複雜度是 O(1),是面試首選。
Dummy Node:讓邊界情況消失的技巧
Linked List 操作最麻煩的是邊界情況:head 是 None 怎麼辦?要插入第一個節點怎麼辦?Dummy Node 是一個虛擬的前置節點,讓你不用對 head 做特殊處理。
#21 Merge Two Sorted Lists
把兩個排序好的 Linked List 合併成一個排序好的 Linked List。
用 Dummy Node + 兩個 pointer 同時遍歷,每次選較小的接上去:
#141 Linked List Cycle:快慢指針
判斷 Linked List 有沒有環(某個節點的 next 指向前面的節點)。
最聰明的解法是 Floyd's Cycle Detection(龜兔賽跑算法):一個慢指針每次走一步,一個快指針每次走兩步。如果有環,快指針一定會追上慢指針;如果沒有環,快指針會先到 None。
有環的情況(1 → 2 → 3 → 4 → 2 loop):
為什麼快指針一定能追上慢指針?
進入環之後,每一輪快指針比慢指針多走一步。如果環長度是 k,最多 k 輪之內,快指針就會追上慢指針。
Linked List 的四個核心技巧
Pointer 反轉
操作前先存好 next_node,避免斷鏈。三個 pointer:prev、curr、next_node。
Dummy Node
在 head 前放虛擬節點,統一邊界處理,最後回傳 dummy.next。
Fast & Slow Pointer
快指針走兩步、慢指針走一步,用來找環、找中點、找倒數第 k 個。
固定間距雙指針
兩個指針保持固定距離,快指針先走 k 步,再同時移動。
Linked List 題目的訣竅:在紙上把節點畫出來,一步一步追蹤 pointer 的位置。寫程式前先確認每一步的狀態,操作前先存好 next,否則一斷鏈就找不回來了。
本篇重點整理
上一篇
EP.07 — Binary Search
每次砍掉一半,O(log n) 的魔法
下一篇
EP.09 — Tree & DFS/BFS
即將推出