12.4 練習
基礎難度
83. Remove Duplicates from Sorted List
雖然 LeetCode 並未強制要求,但我們仍然建議回收記憶體,特別是在題目要求刪除節點時。
題解
問題描述
給定一個已排序的鏈結串列(Linked List),請刪除所有重複的節點,使每個元素只出現一次,並回傳處理後的鏈結串列。
範例
輸入: 1 → 1 → 2
輸出: 1 → 2
輸入: 1 → 1 → 2 → 3 → 3
輸出: 1 → 2 → 3
解題思路:單向遍歷即可
- 因為鏈結串列已經是排序好的,所以只要逐一比較相鄰節點即可。
- 若發現
cur.val == cur.next.val
,表示重複 → 就讓cur.next = cur.next.next
跳過重複節點。 - 否則就往下繼續走。
Python 範例程式碼
class Solution:
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur = head
while cur and cur.next:
if cur.val == cur.next.val:
cur.next = cur.next.next # 跳過重複
else:
cur = cur.next
return head
時間與空間複雜度
- 時間複雜度:,遍歷一次鏈結串列
- 空間複雜度:,原地操作,未使用額外空間
328. Odd Even Linked List
這道題其實很簡單,千萬不要把題目複雜化。
題解
問題描述
給定一個單向鏈結串列,請將所有奇數位置的節點排在偶數位置節點之前,並維持原本相對順序。
位置是從 1
開始計算(不是數值奇偶)。
範例
輸入: 1 → 2 → 3 → 4 → 5
輸出: 1 → 3 → 5 → 2 → 4
輸入: 2 → 1 → 3 → 5 → 6 → 4 → 7
輸出: 2 → 3 → 6 → 7 → 1 → 5 → 4
解題思路:雙指標分流連接
✅ 關鍵觀察
- 題目不是要你按照值的奇偶,而是按照節點位置的奇偶性。
- 我們可以分成兩個鏈:
- 一個鏈接奇數位置的節點
- 一個鏈接偶數位置的節點
- 最後把奇數鏈接到偶數鏈的前面。
步驟
- 建立
odd
指標指向第一個節點,even
指標指向第二個節點 - 記錄
even_head
(最後要接到奇數串列尾巴) - 交替串接奇數與偶數節點直到走完
- 最後把
odd.next = even_head
Python 程式碼
class Solution:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head or not head.next:
return head
odd = head
even = head.next
even_head = even # 記住偶數鏈開頭
while even and even.next:
odd.next = even.next
odd = odd.next
even.next = odd.next
even = even.next
odd.next = even_head
return head
圖解(以 1→2→3→4→5 為例)
初始:
odd: 1 even: 2
第一輪:
odd.next = 3 → odd = 3
even.next = 4 → even = 4
第二輪:
odd.next = 5 → odd = 5
even.next = None → done
最後:
odd.next = even_head(即 2)
→ 結果:1 → 3 → 5 → 2 → 4
時間與空間複雜度
- 時間複雜度:,遍歷一次 所有節點
- 空間複雜度:,原地操作,不需要額外空間
總結
✅ 原地拆解兩條鏈再合併
✅ 雙指標遍歷技巧,是常見的鏈結串列分組類題目
✅ 注意奇偶是「位置」不是「值」!
19. Remove Nth Node From End of List
既然可以使用快慢指針找到鏈結串列的中點,也可以利用類似的方法找到倒數第 N 個節點,無需再次遍歷。