将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 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均按 非递减顺序 排列
方法1 递归:
思路:
需要另外创建一个临时的头结点 pHead
(1) 我们直接将以上递归过程建模,同时需要考虑边界情况。
(2) 如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
时间复杂度:O(m + n) 函数至多只会递归调用每个节点一次。因此,时间复杂度取决于合并后的链表长度,即 O(n+m)
空间复杂度:O(m + n) 每次递归都需要开辟栈空间,栈空间的大小取决于递归调用的深度
方法2 遍历:
需要另外创建一个临时的头结点 pHead
当 l1 和 l2 都不是空链表时,判断 l1 和 l2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。
时间复杂度:O(m + n) while循环的次数不超过两链表长度和,其他操作的时间复杂度是常数级别。
空间复杂度:O(1) 不需要额外存储空间。
// 1.遍历:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* pHead = new ListNode; // 未初始化,头结点值为0,最后返回头结点的next
ListNode* pTemp = pHead;
while (l1 != NULL && l2 != NULL)
{
if (l1->val > l2->val)
{
pTemp->next = l2;
l2 = l2->next;
}
else // 包含等于的情况:l1->val == l2->val
{
pTemp->next = l1;
l1 = l1->next;
}
pTemp = pTemp->next;
}
pTemp->next = (l1 == NULL) ? l2 : l1;
return pHead->next; // 返回头结点的next
}
// 2.递归
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == NULL)
return l2;
else if(l2 == NULL)
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;
}
}

本文介绍两种方法实现两个升序链表的合并:递归和遍历。递归方法通过比较两个链表头部节点值,递归决定结果链表的节点。遍历方法使用一个临时头节点,循环比较两个链表节点值,直至其中一个链表结束。

927





