原题链接:23. 合并K个升序链表
solution:
从合并两个链表的思想出发,循环n次挨个进行合并
class Solution {
public:
//合并两个链表
ListNode *mergetwoLists(ListNode *list1,ListNode *list2) {
ListNode *dummy = new ListNode(-1);
ListNode *cur = dummy;
while(list1 != nullptr && list2 != nullptr) {
if(list1->val <= list2->val) {
cur->next = list1;
cur = cur->next;
list1 = list1->next;
}
else {
cur->next = list2;
cur = cur->next;
list2 = list2->next;
}
}
if(list1 != nullptr) cur->next = list1;
if(list2 != nullptr) cur->next = list2;
return dummy->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
ListNode *dummy = new ListNode(-1);
for(int i = 0;i < n;i++) {
dummy->next = mergetwoLists(dummy->next,lists[i]);
}
return dummy->next;
}
};
利用堆维护每个链表的最小值,每次把堆顶元素出堆插入返回链表的尾部,如果出堆节点不是尾节点,就将其再次入堆。
时间复杂度:nlogk,n为所有链表总长度,k为堆大小
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;
ListNode *dummy = new ListNode(-1);
for(auto &l : lists)
if(l != nullptr )heap.push(l); //将所有链表第一个节点入堆,并按升序排列
ListNode *cur = dummy;
while(!heap.empty()) {
auto t = heap.top();
heap.pop();
cur->next = t; //cur指向最小的链表值
cur = cur->next;
if(t->next != nullptr) heap.push(t->next); //如果t还有下一个节点,将下一个节点入堆
}
return dummy->next;
}
};