使用大根堆里存储链表节点值的相反数——
priority_queue[HTML_REMOVED]> heap;
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<pair<int, ListNode*>> heap;
auto dummy = new ListNode(-1), tail = dummy;
for (auto list : lists) {
if (list) heap.push({-list->val, list});
}
while (heap.size()) {
auto t = heap.top();
heap.pop();
tail = tail->next = t.second;
auto p = t.second->next;
if (p) heap.push({-p->val, p});
}
return dummy->next;
}
};
二分治合并(基于二路归并思想) 参考题解1
参考题解2 使用默认大根堆,但是需要存储值的相反数
在堆中存储的是一对pair,其中第一个值就是指针指向的值,第二个值为当前指针。当每个元素在小根堆中排序时,默认根据第一维,即对每个指针指向结点的值进行排序。
参考题解3 我不是张小白 CSDN上的题解
class Solution {
public:
ListNode* merge2Lists(ListNode* l1, ListNode* l2) {
auto dummy = new ListNode(-1), tail = dummy;
while (l1 && l2) {
if (l1->val > l2->val) {
tail = tail->next = l2;
l2 = l2->next;
}
else {
tail = tail->next = l1;
l1 = l1->next;
}
}
tail = tail->next = (l1? l1 : l2);
return dummy->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.size() == 0) return NULL;
if (lists.size() == 1) return lists[0];
int mid = lists.size() / 2;
vector<ListNode*> left = vector<ListNode*>(lists.begin(), lists.begin() + mid);
vector<ListNode*> right = vector<ListNode*>(lists.begin() + mid, lists.end());
ListNode* l1 = mergeKLists(left);
ListNode* l2 = mergeKLists(right);
return merge2Lists(l1, l2);
}
};
yxc代码参考
class Solution {
public:
struct Cmp {
bool operator() (ListNode* a, ListNode* b) {
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, Cmp> heap;
auto dummy = new ListNode(-1), tail = dummy;
for (auto l : lists) if (l) heap.push(l);
while (heap.size()) {
auto t = heap.top();
heap.pop();
tail = tail->next = t;
if (t->next) heap.push(t->next);
}
return dummy->next;
}
};
小根堆的另一种定义方式
class Solution {
public:
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;
}
};
另一种归并方式写法
先将K个链表分成两个部分,先合并两个部分,在合并这两个部分返回的链表。
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;
}
}
大佬实在太多了,加油呀!