题面
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:

输入: l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
示例 2:
输入: l1 = [], l2 = [] 输出:[]
示例 3:
输入: l1 = [], l2 = [0] 输出:[0]
提示:
- 两个链表的节点数目范围是
[0, 50] -100 <= Node.val <= 100l1和l2均按 非递减顺序 排列
分析
-
显然,可以使用两个指针,遍历之后就将另一个链表的节点加入到另一个链表中
-
代码实现
/** * 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* mergeTwoLists(ListNode* list1, ListNode* list2) { if (list1 == nullptr) return list2; if (list2 == nullptr) return list1; ListNode *p1 = list1, *p2 = list2; ListNode *pre = nullptr, *res = p1; while (p2 != nullptr) { while (p1 != nullptr && p2->val > p1->val) { pre = p1; p1 = p1->next; } ListNode* temp = p2->next; if (pre != nullptr) pre->next = p2; else res = p2; p2->next = p1; p1 = p2; p2 = temp; } return res; } }; -
可以添加一个虚拟头节点,来避免处理 pre == nullptr 的额外逻辑
/** * 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* mergeTwoLists(ListNode* list1, ListNode* list2) { // 定义哑节点(哨兵节点),初始值任意,仅作为临时头节点 ListNode* dummy = new ListNode(-1); // 定义一个指针cur,用于遍历并构建新链表 ListNode* cur = dummy; // 当两个链表都不为空时,比较当前节点值,选择更小的接入新链表 while (list1 != nullptr && list2 != nullptr) { if (list1->val <= list2->val) { cur->next = list1; // 接入list1的当前节点 list1 = list1->next;// list1指针后移 } else { cur->next = list2; // 接入list2的当前节点 list2 = list2->next;// list2指针后移 } cur = cur->next; // cur指针后移,准备接入下一个节点 } // 处理剩余的节点(其中一个链表已遍历完,直接接入另一个的剩余部分) cur->next = list1 != nullptr ? list1 : list2; // 哑节点的next才是真正的头节点,最后释放哑节点避免内存泄漏 ListNode* res = dummy->next; delete dummy; return res; } }; -
通过哑节点,可以将根据大小的比较,逐个将新节点移动到哑节点上,避免直接将节点挪到另一个链表上时的复杂逻辑
-
也可以用递归来实现,递归逻辑如下
-
即,两个链表头部值较小的一个节点与剩下元素的
merge操作结果合并 -
代码实现如下
class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (l1 == nullptr) { return l2; } else if (l2 == nullptr) { return l1; } else if (l1->val < l2->val) { l1->next = mergeTwoLists(l1->next, l2); return l1; } else { l2->next = mergeTwoLists(l1, l2->next); return l2; } } };
这篇文档有帮助吗?