LeetCode C++16-合并K个升序链表

题目描述

        给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序的链表中,返回合并后的链表。

示例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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值