目录
题目描述
方法一、k-1次两两合并
选第一个链表作为结果链表,每次将后面未合并的链表合并到结果链表中,经过k-1次合并,即可得到答案。假设每个链表的最长长度是n,时间复杂度O(n+2n+3n+...(k-1)n) = O(n) = O(
n)。空间复杂度O(1)。
/**
* 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;
ListNode* ans = lists[0];
for(int i = 1;i< n;i++){
ans = merge(ans,lists[i]);
}
return ans;
}
ListNode* merge(ListNode* L1,ListNode* L2){
ListNode* dummy = new ListNode();
ListNode* cur = dummy;
while(L1&&L2){
if(L1->val < L2->val){
cur->next = L1;
cur = L1;
L1 = L1->next;
}else{
cur->next = L2;
cur = L2;
L2 = L2->next;
}
}
cur->next = L1 != nullptr ? L1 : L2;
ListNode* res = dummy->next;
delete dummy;
return res;
}
};
方法二、分治法合并
时间复杂度 O(kn×logk)。空间复杂度 O(logk) 。
/**
* 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;
return merge(lists,0,n-1);
}
ListNode* merge(vector<ListNode*>& lists,int left,int right){
if(left == right)
return lists[left];
if(left>right)
return nullptr;
int mid = left + ((right-left)>>1);
return mergeTwoList(merge(lists,left,mid),merge(lists,mid+1,right));
}
ListNode* mergeTwoList(ListNode* L1,ListNode* L2){
ListNode* dummy = new ListNode();
ListNode* cur = dummy;
while(L1&&L2){
if(L1->val < L2->val){
cur->next = L1;
cur = L1;
L1 = L1->next;
}else{
cur->next = L2;
cur = L2;
L2 = L2->next;
}
}
cur->next = L1 != nullptr ? L1 : L2;
ListNode* res = dummy->next;
delete dummy;
return res;
}
};
方法三、使用优先队列
时间复杂度 O(kn×logk)。空间复杂度 O(k) 。
/**
* 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 {
struct Node{
ListNode* node_ptr;
int val;
bool operator<(const Node& rhs) const{
return val>rhs.val;
}
};
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<Node> Heap;
for(auto& node:lists){
if(node){
Heap.push({node,node->val});
}
}
ListNode* head = nullptr;
ListNode* cur = nullptr;
while(!Heap.empty()){
if(head == nullptr){
head = Heap.top().node_ptr;
cur = head;
}else{
cur->next = Heap.top().node_ptr;
cur = cur->next;
}
Heap.pop();
if(cur->next){
Heap.push({cur->next,cur->next->val});
}
}
return head;
}
};