MediumRating 1327
2095. Delete the Middle Node of a Linked List
linked-listtwo-pointers
解題說明
Delete the Middle Node of a Linked List
題目描述:給定一個鏈結串列,刪除中間節點並回傳修改後的串列頭節點。中間節點定義為從 0 開始編號後第 ⌊n/2⌋ 個節點(n 為串列長度)。例如長度 5 時刪除第 2 個(0-indexed),長度 6 時刪除第 3 個。
解題思路:使用快慢指標(Floyd 龜兔算法的變體)。slow 每次走一步,fast 每次走兩步。當 fast 走到末尾時,slow 恰好在中間節點。為了刪除 slow,需要一個 prev 指標追蹤 slow 的前一個節點。使用啞節點(dummy node)指向頭部可以統一處理邊界情況。
C++ 解法
複雜度分析
時間複雜度:O(n) — fast 指標走完整個串列,slow 走一半。
空間複雜度:O(1) — 只使用常數個指標,無額外資料結構。
虛擬碼
1. Create dummy node pointing to head 2. slow = head, fast = head, prev = dummy 3. While fast != null AND fast.next != null: a. prev = slow b. slow = slow.next c. fast = fast.next.next 4. // slow is the middle node 5. prev.next = slow.next // delete middle 6. Return dummy.next
其他解法
兩次遍歷 O(n):第一次遍歷計算串列長度 n,第二次遍歷走到第 ⌊n/2⌋ - 1 個節點並刪除其後繼。邏輯簡單直觀,但需要兩次線性掃描。
收集節點陣列 O(n) 空間:將所有節點存入 vector,直接用下標定位中間節點並刪除。程式碼最簡短,但需 O(n) 額外空間,不適合記憶體受限的場景。
延伸思考
- 若要同時刪除前 1/3 和後 1/3 之間的所有節點(只保留頭尾各 1/3),快慢指標能否擴展應用?
- 快慢指標在長度為偶數時找的是前半段末尾還是後半段開頭?本題的
⌊n/2⌋定義如何影響指標移動的終止條件? - 如何修改此演算法以刪除距離尾端第 k 個節點(LC 19 的變體)?