[Leetcode解題] 206. Reverse Linked List
21 March 2025
easy
linked-list
題目
206. Reverse Linked List
給定一個單向鏈結串列的頭節點 head
,請你將整個鏈結串列反轉,並回傳反轉後的頭節點。
範例
範例 1
輸入:head = [1,2,3,4,5]
輸出:[5,4,3,2,1]
範例 2
輸入:head = [1,2]
輸出:[2,1]
範例 3
輸入:head = []
輸出:[]
解題思路
我們可以使用 兩種方法 來解這題:
- 迭代法 (Iterative Approach) → 使用三個指標 (
prev, curr, next
) - 遞迴法 (Recursive Approach) → 遞迴反轉每個節點
方法 1:迭代法
我們可以使用三個指標來處理:
prev
指向已經反轉的部分 (初始為NULL
)curr
指向目前要處理的節點next
暫存curr
的下一個節點,避免鏈結遺失
反轉的步驟如下:
- 用
next
暫存curr->next
- 把
curr->next
指向prev
prev
移動到curr
curr
移動到next
- 直到
curr
變成NULL
,此時prev
就是新的頭節點
時間複雜度:O(n)
空間複雜度:O(1) (只使用了額外的指標)
方法 2:遞迴法
在遞迴方法中,每次反轉 head->next
,然後將 head->next->next = head
來讓下一個節點指向自己,最後把 head->next
設為 NULL
。
遞迴的核心步驟:
- 如果
head
為空或head->next
為空,直接回傳head
(表示只有一個節點) - 遞迴處理
head->next
- 反轉
head->next->next = head
head->next = NULL
- 回傳新的頭節點
時間複雜度:O(n)
空間複雜度:O(n) (遞迴的堆疊佔用)
C++ 解法
方法 1:迭代法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = NULL;
ListNode* curr = head;
ListNode* next;
while (curr) {
next = curr->next; // 暫存下一個節點
curr->next = prev; // 反轉指標
prev = curr; // prev 前進
curr = next; // curr 前進
}
return prev; // 最後 prev 會是新的頭
}
};
方法 2:遞迴法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next) return head; // base case
ListNode* newHead = reverseList(head->next); // 反轉剩下的部分
head->next->next = head; // 讓下一個節點指向自己
head->next = NULL; // 斷開原本的連結
return newHead;
}
};
Python 解法
方法 1:迭代法
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
curr = head
while curr:
next_node = curr.next # 暫存下一個節點
curr.next = prev # 反轉指標
prev = curr # prev 前進
curr = next_node # curr 前進
return prev # prev 變成新的頭節點
方法 2:遞迴法
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head or not head.next:
return head # base case
new_head = self.reverseList(head.next) # 反轉剩下的部分
head.next.next = head # 讓下一個節點指向自己
head.next = None # 斷開原本的連結
return new_head
時間與空間複雜度分析
- 迭代法: 時間複雜度$O(n)$, 空間複雜度$O(1)$
- 遞迴法: 時間複雜度$O(n)$, 空間複雜度$O(n)$ (遞迴堆疊)
如果 記憶體有限,建議使用 迭代法,因為它只需要幾個指標變數,不會佔用額外的遞迴堆疊空間。