合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
算法1:顺序枚举 ![O(k^2n)](https://i-blog.csdnimg.cn/blog_migrate/14bb526365af279f7f6304c5dc5bc862.gif)
每次取数组中的2个链表来merge,每次时间复杂度是,空间复杂度是
要执行k次,k为数组的长度
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.empty()) return nullptr;
if (lists.size() <= 1) return lists.back();
while (lists.size() > 1) {
auto l1 = lists.back();
lists.pop_back();
auto l2 = lists.back();
lists.pop_back();
lists.push_back(merge(l1, l2));
}
return lists.back();
}
ListNode* merge(ListNode* root1, ListNode* root2) {
auto dummy = new ListNode(-1);
auto p1 = root1, p2 = root2;
auto p = dummy;
while (p1 && p2) {
if (p1->val <= p2->val) {
p->next = p1, p1 = p1->next, p = p->next;
} else {
p->next = p2, p2 = p2->next, p = p->next;
}
}
if (p1) {
p->next = p1;
}
if (p2) {
p->next = p2;
}
return dummy->next;
}
};
算法2:分治枚举 ![O(logk * kn)](https://i-blog.csdnimg.cn/blog_migrate/ee9ab56dcc9eccc992b17ee57a85c4d3.gif)
按照归并排序的思想,两两合并,第一次合并组链表,第二次合并
组链表...,每次的时间复杂度为
一共执行次,所以时间复杂度为
,空间复杂度为递归调用的栈空间
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
return merge_list(lists, 0, lists.size() - 1);
}
ListNode* merge_list(vector<ListNode*>& lists, int l, int r) {
if (l > r) return NULL;
if (l == r) return lists[l];
int mid = l + r >> 1;
auto left = merge_list(lists, l, mid);
auto right = merge_list(lists, mid + 1, r);
return merge(left, right);
}
ListNode* merge(ListNode* root1, ListNode* root2) {
auto dummy = new ListNode(-1);
auto p1 = root1, p2 = root2;
auto p = dummy;
while (p1 && p2) {
if (p1->val <= p2->val) {
p->next = p1, p1 = p1->next, p = p->next;
} else {
p->next = p2, p2 = p2->next, p = p->next;
}
}
if (p1) {
p->next = p1;
}
if (p2) {
p->next = p2;
}
return dummy->next;
}
};