方法1:递归
思路
merge
操作(忽略边界情况,比如空链表等):即两个链表头部值较小的一个节点与剩下元素的 merge
操作结果合并
l1
或者 l2
一开始就是空链表 ,那么没有任何操作需要合并,所以只需要返回非空链表。l1
和 l2
哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。Code
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l2) {
return l1;
}
else if (!l1) {
return l2;
}
else if (l1->val > l2->val) {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
else {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
}
};
复杂度分析
l1
或者 l2
的头节点,直到至少有一个链表为空,函数 mergeTwoList 至多只会递归调用每个节点一次。方法2:迭代
思路
l1
和 l2
都不是空链表时,判断 l1
和 l2
哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。dummy
,方便返回合并后的链表。维护一个 node
指针,不断调整它的 next
指针。重复以下过程,直到 l1
或者 l2
指向了 null
:如果 l1
当前节点的值小于等于 l2
,把 l1
当前的节点接在 node
节点的后面同时将 l1
指针往后移一位。否则,对 l2
做同样的操作。不管将哪一个元素接在了后面,都需要将 node
向后移一位。l1
和 l2
至多有一个是非空的。由于输入的两个链表都是有序的,只需要将非空链表接在合并链表的后面,并返回合并链表即可Code
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
//设置哨兵节点和遍历节点
ListNode *dummy = new ListNode(0), *node = dummy;
while (l1 && l2) {
//获取下一个节点
if (l1->val <= l2->val) {
node->next = l1;
l1 = l1->next;
}
else {
node->next = l2;
l2 = l2->next;
}
//连接节点
node = node->next;
}
//合并后l1和l2最多只有一个还未被合并完,直接将链表末尾指向未合并完的链表
node->next = l1 ? l1 : l2;
return dummy->next;
}
};
复杂度分析
l1
和 l2
只有一个元素会被放进合并链表中, 因此 while
循环的次数不会超过两个链表的长度之和。原文:https://www.cnblogs.com/bky-hbq/p/13171957.html