【LeetCode Hot 100】23. 合并K个升序链表

news/2024/9/30 23:07:18

题目描述

看到这个题目会想起之前做过的合并2个升序链表。在那个题目中,由于两个链表都已经是升序的,可以将两个链表的元素进行逐个比较并添加到答案链表中。但是在本题中,每次循环都需要在k个链表的当前元素中找出最小的,而且需要在所有k个链表都遍历完之后跳出循环,所以效率比较低。

class Solution {
public:bool checkIsEnd(vector<ListNode*>& lists) {for (int i = 0; i < lists.size(); i++) {if (lists[i] != nullptr) return false;}return true;}ListNode* mergeKLists(vector<ListNode*>& lists) {if (lists.empty()) return nullptr;ListNode* dummy = new ListNode();ListNode* p = dummy;int k = lists.size();while (true) {if (checkIsEnd(lists)) break;ListNode* minNode = nullptr;int minNodeIdx = -1;for (int i = 0; i < k; i++) {if (lists[i] == nullptr) continue;if (minNode == nullptr || minNode->val > lists[i]->val) {minNode = lists[i];minNodeIdx = i;}}p->next = minNode;p = p->next;lists[minNodeIdx] = lists[minNodeIdx]->next;}return dummy->next;}
};

这种方法中影响时间效率的主要在于:每次循环都需要首先判断指针是否已经到达链表结尾,以及每次比较k个元素的最小值都需要遍历k个元素。这里我的一个想法是优化第一个点:使用一个bitmap存储第i个链表是否已经达到结尾,这样直接进行位运算比通过循环进行判断效率高得多,但是由于需要k位长的bit串,而题目中k的设置可以非常大,超过计算机的极限,因此这个方法不太合适。

能否使用优先队列(堆)解决k个元素的最小值的问题?可以构建一个优先队列,内部维护k个当前链表结点,每次pop出最小的结点(相当于第一种方法中将最小结点加入答案链表中),再把后面一个结点加入优先队列中(相当于第一种方法中将指针向前移动一个结点),这样循环,直到优先队列中没有剩余元素为止,说明所有k个链表中的所有元素已经比较完毕了。

class Solution {
public:struct Node {ListNode* ptr;bool operator<(const Node& rhs) const {return ptr->val > rhs.ptr->val;}};priority_queue<Node> q;ListNode* mergeKLists(vector<ListNode*>& lists) {for (ListNode* node : lists) {if (node != nullptr) {q.push({node});}}ListNode *head = new ListNode(), *tail = head;while (!q.empty()) {Node node = q.top();q.pop();tail->next = node.ptr;tail = tail->next;if (node.ptr->next) {q.push({node.ptr->next});}}return head->next;}
};

其实从合并2个有序链表的想法出发,可以采用类似分治、合并的方法,比如:顺序合并,用一个链表ans来维护已经合并的链表,然后循环k次,第i次合并第i个链表,最终把所有链表合并进去;分治合并,将k个链表分组配对,并将每一对中的链表进行两两合并,如此进行多轮合并直到剩下一个链表作为答案。这两种方法也是官方题解给出的前两种解法,想法是将问题归约为合并2个有序链表的方法,并直接利用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66675.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

opencascade AIS_WalkDelta、AIS_ViewInputBuffer源码学习工作

opencascade AIS_WalkDelta 前言 运行方法 1. 空构造函数。 AIS_WalkDelta() : myIsDefined(false), myIsJumping(false), myIsCrouching(false), myIsRunning(false) {} 2. 返回平移组件。 const AIS_WalkPart& operator[] (AIS_WalkTranslation thePart) ; 3. 返回平移组…

2023-9-30

标签之文本标签列表标签之有序列表列表标签之无序列表

[物理]运动学基础理论串讲

运动学基础理论串讲 公式 推论 前言:运动学中,所有的公式都有其对应的几何意义。解决问题时,我们不应死套公式,应当在图像中解决问题。在图像中看清问题的本质。 \(v_t=v_0+at\)。已知初速度和加速度求末速度。 \(x=v_0t+\dfrac{1}{2}at^2\)。算位移的基础公式。 \(v_t^2-…

深度学习(输出模型中间特征)

深度学习骨干网络一般会包含很多层,这里写了一个脚本,可以保存骨干网络的所有特征图。 代码主要用了get_graph_node_names和create_featrue_extractor这两个函数。 get_graph_node_names是得到所有特征节点名字。 create_featrue_extractor是提取对应节点输出的特征tensor。 …

9月30日记录

完成了一个能够列出30道四则运算的java程序, 题目要求:乘法不超过四位数,减法大于零,除法结果为整数; 实现可视化界面,并且能够计算得分与计时;点击查看代码 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.Actio…

9.28 开发MES系统日志四

今天开发MES系统的流程图以及数据库表,因为对MES系统的不了解,所以先加上了最基本的人员管理以及车间管理等基本表信息。

Connector C++ 连接 MySQL 数据库之增删改查

在 vcpkg 中折腾了 mysql-connector-cpp 8.0 很久,一直连接不上远程数据库,后面查官方文档,mysql-connector-cpp 8.0 好像只支持 MySQL 8.0 以上的数据库,本来想把远程服务器上的 MySQL 升级到 MySQL 8.0,后面发现测试服务器的配置有点拉跨,架不住 MySQL 8.0,但是 vcpkg…

Hadoop 配置hbase

首先要启动hadoop start-dfs.shstart-yarn.sh 查看一下自己的hadoop版本,确保自己下载的hbase与自己的hadoop版本匹配 hadoop version Index of /apache/hbase (tsinghua.edu.cn) 下载hbase 选择倒数第三个下载 下载完成后 进入 /export/server/ 上传压缩包后 完成解压 重命…