题目描述
给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序的链表中,返回合并后的链表。
示例1:
输入: lists: 1->4->5, 1->3->4, 2->6
输出: 1->1->2->3->4->4->5->6
示例2:
输入: []
输出:[]
示例3:
输入: [[]]
输出: []
解题方法:最小堆实现。用小顶堆保存每个链表当前遍历到的最小元素,每次弹出栈顶元素合并到新的链表中,并将栈顶元素的下一个非空的节点压入栈。
代码
#include <iostream>
#include <vector>
#include <functional> // lambda, function
#include <queue> // std::priority_queue
#include <memory> // std::shared_ptr
struct Node {
int value;
Node* next;
Node(int value) {
this->value = value;
next = nullptr;
}
};
Node* merge_list(std::vector<Node*> head_list) {
auto cmp = [](Node* left, Node* right) { //类似std::greater,小顶堆
return left->value > right->value;
};
std::priority_queue<Node*, std::vector<Node*>, decltype(cmp)> q(cmp); //注意:这个需要带一个cmp的参数,否则会有core
std::shared_ptr<Node> dummy_node(new Node(-1));
Node* p = dummy_node.get();
for (auto phead : head_list) { //将每个链表的头节点压入优先级队列中
if (phead == nullptr) {
continue;
}
q.push(phead);
}
Node* src_ptr = nullptr;//标记来源数组
while (!q.empty()) {
//出栈,将栈顶元素合入
src_ptr = q.top();
q.pop();
p->next = src_ptr;
if (src_ptr->next != nullptr) { //将来源数组下一个节点压入队列中
q.push(src_ptr->next);
}
p = p->next;
}
return dummy_node->next;
}
void print_node(Node* head) {
if (!head) {
return;
}
Node* p = head;
while (p) {
std::cout << p->value << "->";
p = p->next;
}
std::cout << "nullptr" << std::endl;
}
int main()
{
Node n10(1), n11(4), n12(5);
Node n20(1), n21(3), n22(4);
Node n30(2), n31(6);
std::cout << "input:" << std::endl;
// head1
n10.next = &n11;
n11.next = &n12;
Node* head1 = &n10;
print_node(head1);
// head2
n20.next = &n21;
n21.next = &n22;
Node *head2 = &n20;
print_node(head2);
// head3
n30.next = &n31;
Node* head3 = &n30;
std::vector<Node*> lists = {head1, head2, head3};
print_node(head3);
// merge
Node *head = merge_list(lists);
std::cout << "output:" << std::endl;
print_node(head);
return 0;
}
代码运行结果如下:
input:
1->4->5->nullptr
1->3->4->nullptr
2->6->nullptr
output:
1->1->2->3->4->4->5->6->nullptr