將兩個升序鏈表合併為一個新的升序鏈表,並返回合併後的頭節點。要求原地操作,不創建新節點。
維護三個指針:
l1、l2:分別指向兩個鏈表當前待處理節點cur:指向新鏈表尾部,用於連接較小節點每輪比較 l1->val 和 l2->val,將較小者接到 cur->next,並推進對應指針。
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
// 邊界處理
if (!l1) return l2;
if (!l2) return l1;
// 確定新頭節點
ListNode* head = nullptr;
if (l1->val <= l2->val) {
head = l1; l1 = l1->next;
} else {
head = l2; l2 = l2->next;
}
head->next = nullptr; // 斷開原連接
ListNode* cur = head;
// 合併主循環
while (l1 && l2) {
if (l1->val <= l2->val) {
cur->next = l1;
l1 = l1->next;
} else {
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
cur->next = nullptr; // 重要:斷開舊連接,防止殘留指針
}
// 接上剩餘部分
if (l1) cur->next = l1;
if (l2) cur->next = l2;
return head;
}
};
cur->next = nullptr 防止原鏈表殘留指針導致環或錯誤連接ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l1) return l2;
if (!l2) return l1;
if (l1->val <= l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
| 方法 | 時間 | 空間 | 優點 |
|---|---|---|---|
| 迭代 | O(n+m) | O(1) | 原地、無棧溢出風險 |
| 遞歸 | O(n+m) | O(n+m) | 代碼極簡、邏輯清晰 |
l1: 1->2->4, l2: 1->3->4 -> 1->1->2->3->4->4 l1: null, l2: 0 -> 0 l1: 5, l2: 1->2->3 -> 1->2->3->5