1. 题目来源
链接:21. 合并两个有序链表
2. 题目解析
经典的二路归并算法,在这应用到链表中,要注意虚拟头结点和尾指针的使用。
关于递归写法在这并不是那么好理解,建议去看看题解区的大佬图解。其实就是递归实现的一个二路归并过程,只不过每次只是完成的两个节点的比较合并,每次递归过程都会将链表长度减 1,等于每次都是个新的链表,我觉得理解这个是重要的。然后最后递归返回,一层一层的返回最终答案。模拟样例,帮助理解,真事!
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
// 链表二路归并
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
auto dummy = new ListNode(-1), cur = dummy;
while (l1 && l2) {
if (l1->val > l2->val) {
cur = cur->next = l2;
l2 = l2->next;
} else {
cur = cur->next = l1;
l1 = l1->next;
}
}
if (l1) cur->next = l1;
if (l2) cur->next = l2;
return dummy->next;
}
};
// 递归写法
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (!l1) return l2;
else if (!l2) return l1;
else if (l1->val > l2->val) { l2->next = mergeTwoLists(l1, l2->next); return l2; }
else { l1->next = mergeTwoLists(l1->next, l2); return l1; }
}
};