解法一:优先队列
每次队列中存储第一个元素以及索引,弹出最小元素对应位置的数组位置+1
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
typedef pair<int, int> P;
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *dummy = new ListNode(), *p = dummy;
priority_queue<P> q;
int n = lists.size();
vector<int> pos(n, 1);
for(int i=0;i<n;i++)
{
auto n = lists[i];
if(n)
{
q.push(P(-n->val, i));
n = n->next;
}
}
while(q.size() > 0)
{
auto top = q.top();
q.pop();
auto idx = top.second;
auto n = lists[idx];
p->next = n;
p = p->next;
if(n->next)
{
lists[idx] = n->next;
q.push(P(-n->next->val, idx));
}
}
p = p->next;
return dummy->next;
}
};
解法二:归并法
和迭代型的归并排序类似,我们需要两两合并链表,以达到O(logN)的效果。为了方便,我们每次都把结果存在左边的链表,最后返回lists[0]即可。在操作时,遵循自底向上step模板(可先学迭代版归并排序)此题操作要稍微简单些。
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
if(n == 0)return nullptr;
for(int step=1;step<n;step*=2)
{
for(int i=0;i+step<n;i+=step*2)
{
ListNode *l = lists[i], *r = lists[i+step];
// 合并r到l
ListNode *dummy = new ListNode();
ListNode *last = dummy;
while(l && r)
{
if(l->val <= r->val)
{
last->next = l;
l = l->next;
}
else
{
last->next = r;
r = r->next;
}
last = last->next;
}
while(l)last->next = l, l=l->next, last = last->next;
while(r)last->next = r, r=r->next, last = last->next;
lists[i] = dummy->next;
}
}
return lists[0];
}
};