题目描述
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
题意:合并K个有序链表。
算法1
分治算法
题解1:分治,先将K个链表分成两个部分,先合并两个部分,在合并这两个部分返回的链表。
C++ 代码
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
if(n == 0) return NULL;
return merge(lists,0,n - 1);
}
ListNode* merge(vector<ListNode*>& lists,int begin,int end)
{
if(begin == end)
return lists[begin];
else{
int mid = (begin + end) /2;
ListNode* l1 = merge(lists,begin,mid);
ListNode* l2 = merge(lists,mid+1,end);
ListNode* dummy = new ListNode(0);
ListNode* cur = dummy;
while(l1 && l2)
{
if(l1->val < l2->val)
{
cur->next = new ListNode(l1->val);
l1 = l1->next;
}else{
cur->next = new ListNode(l2->val);
l2 = l2->next;
}
cur = cur->next;
}
cur->next = (l1)?l1:l2;
return dummy->next;
}
}
算法2
优先队列
类似于Leetcode786题,每次取出链表头节点进入优先队列,弹出堆顶元素时,将该节点的后驱节点加入优先队列。
自己也想到了这样的思路,但是不太会写自定义比较函数,所以参考了别人的。
C++ 代码
ListNode* mergeKLists(vector<ListNode*>& lists) {
auto cmp = [](ListNode*& a, ListNode*& b) {
return a->val > b->val;
};
priority_queue<ListNode*, vector<ListNode*>, decltype(cmp) > q(cmp);
for (auto node : lists) {
if (node) q.push(node);
}
ListNode *dummy = new ListNode(-1), *cur = dummy;
while (!q.empty()) {
auto t = q.top(); q.pop();
cur->next = t;
cur = cur->next;
if (cur->next) q.push(cur->next);
}
return dummy->next;
}