23. 合并 K 个升序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
https://leetcode.cn/problems/merge-k-sorted-lists/description/
方法三:堆
/**
* 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:
struct Status {
int val;
ListNode* ptr;
bool operator<(const Status& t) const {
return val > t.val; // 重写大顶堆定义,从大顶堆改为小顶堆
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<Status> q;
for (int i = 0; i < lists.size(); i++) {
if (lists[i]) {
q.push({lists[i]->val, lists[i]});
}
}
ListNode head, *tail = &head;
while (!q.empty()) {
Status minest = q.top();
q.pop();
tail->next = minest.ptr;
tail = tail->next;
if (minest.ptr->next) {
q.push({minest.ptr->next->val, minest.ptr->next});
}
}
return head.next;
}
};
方法2:递归
加入了了递归,减少比对的次数
/**
* 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 list_num = lists.size();
ListNode *head = nullptr, *p = nullptr;
if(list_num==1){
return lists[0];
}
else if(list_num>2){
vector<ListNode*> new_lists;
int mid = list_num/2;
for(int i=0;i<mid;i++){
new_lists.push_back(lists.back());
lists.pop_back();
}
ListNode* l1 = mergeKLists(new_lists);
ListNode* l2 = mergeKLists(lists);
lists.clear();
lists.push_back(l1);
lists.push_back(l2);
}
list_num = lists.size();
while (true) {
int valid_list_num = 0;
int minest = 1000000;
int idx = -1;
// 在链表里面找到最小的
for (int i = 0; i < list_num; i++) {
if (lists[i]) {
valid_list_num += 1;
if (minest > lists[i]->val) {
idx = i;
minest = lists[idx]->val;
}
}
}
// 如果没找到,说明没有最小的,全都找过了
if (idx == -1) {
return head;
}
if (!head) {
head = lists[idx];
p = head;
} else {
if (valid_list_num == 1) {
p->next = lists[idx];
return head;
}
p->next = lists[idx];
p = p->next;
}
lists[idx] = lists[idx]->next;
}
return head;
}
};
方法一:暴力破解
最朴素地循环比对每一个链表的头节点
/**
* 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 list_num = lists.size();
ListNode *head = nullptr, *p = nullptr;
while (true) {
int valid_list_num = 0;
int minest = 1000000;
int idx = -1;
// 在链表里面找到最小的
for (int i = 0; i < list_num; i++) {
if (lists[i]) {
valid_list_num += 1;
if (minest > lists[i]->val) {
idx = i;
minest = lists[idx]->val;
}
}
}
// 如果没找到,说明没有最小的,全都找过了
if (idx==-1) {
return head;
}
if (!head) {
head = lists[idx];
p = head;
} else {
if (valid_list_num == 1) {
p->next = lists[idx];
return head;
}
p->next = lists[idx];
p = p->next;
}
lists[idx] = lists[idx]->next;
}
return head;
}
};