12.2 鏈結串列的基本操作
206. Reverse Linked List
題目描述
翻轉一個鏈結串列。
輸入輸出範例
輸入一個鏈結串列,輸出該鏈結串列翻轉後的結果。
Input: 1->2->3->4->5->nullptr
Output: 5->4->3->2->1->nullptr
題解
鏈結串列翻轉是非常基礎也必須掌握的技能。我們提供了兩種寫法——遞迴和非遞迴。建議同時掌握這兩種寫法。
遞迴的寫法為:
- C++
- Python
ListNode* reverseList(ListNode* head, ListNode* head_prev = nullptr) {
if (head == nullptr) {
return head_prev;
}
ListNode* head_next = head->next;
head->next = head_prev;
return reverseList(head_next, head);
}
def reverseList(
head: Optional[ListNode], head_prev: Optional[ListNode] = None
) -> Optional[ListNode]:
if head is None:
return head_prev
head_next = head.next
head.next = head_prev
return reverseList(head_next, head)
複雜度分析 (遞迴)
- 時間複雜度: ,其中 是鏈結串列的長度,每個節點只會被處理一次。
- 空間複雜度: ,主要來自遞迴堆疊的深度,最壞情況下一層一層疊到 。
非遞迴的寫法為:
- C++
- Python
ListNode* reverseList(ListNode* head) {
ListNode *head_prev = nullptr, *head_next;
while (head) {
head_next = head->next;
head->next = head_prev;
head_prev = head;
head = head_next;
}
return head_prev;
}
def reverseList(head: Optional[ListNode]) -> Optional[ListNode]:
head_prev = None
while head is not None:
head_next = head.next
head.next = head_prev
head_prev = head
head = head_next
return head_prev
複雜度分析 (迴圈)
- 時間複雜 度: ,其中 是鏈結串列的長度,每個節點只會被遍歷一次。
- 空間複雜度: ,只用了固定的幾個指標,不需要額外空間。
21. Merge Two Sorted Lists
題目描述
給定兩個遞增排序的鏈結串列,將它們合併成一個遞增排序的鏈結串列。
輸入輸出範例
輸入:兩個鏈結串列。
輸出:一個鏈結串列,表示合併的結果。
Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4
題解
我們提供遞迴與非遞迴兩種寫法。
遞迴的寫法如下:
- C++
- Python
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l2 == nullptr) {
return l1;
}
if (l1 == nullptr) {
return l2;
}
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
def mergeTwoLists(
l1: Optional[ListNode], l2: Optional[ListNode]
) -> Optional[ListNode]:
if l1 is None or l2 is None:
return l1 or l2
if l1.val < l2.val:
l1.next = mergeTwoLists(l1.next, l2)
return l1
l2.next = mergeTwoLists(l1, l2.next)
return l2