【C++】LeetCode:LCR 078. 合并 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) {}* };*/auto cmp = [](ListNode*a,ListNode*b){return a->val>b->val;
};
class Solution {
public:ListNode * mergeTwoLists(ListNode * a,ListNode * b){ListNode * dummy = new ListNode(0);ListNode * cur = dummy;while (a!= nullptr&&b!= nullptr){if (a->val<b->val){cur->next = a;a = a->next;} else{cur->next = b;b = b->next;}cur = cur->next;}cur->next = (a== nullptr)?b:a;return dummy->next;};ListNode *mergeKLists(std::vector<ListNode*>& lists){std::priority_queue<ListNode*,std::vector<ListNode*>, decltype(cmp)> minHeap(cmp);for (auto list:lists) {if(list!= nullptr){minHeap.push(list);}}ListNode dummy = ListNode(0);ListNode * tail = &dummy;while (!minHeap.empty()){ListNode * miniNode = minHeap.top();minHeap.pop();tail->next = miniNode;tail = tail->next;if (miniNode->next!= nullptr){minHeap.push(miniNode->next);}}return  dummy.next;};
};

举例分步解析:

示例:合并三个升序链表

假设我们有三个升序链表:

  1. 链表 11 -> 4 -> 5
  2. 链表 21 -> 3 -> 4
  3. 链表 32 -> 6

初始化状态:

最小堆的基本概念

  • 最小堆 是一种特殊的二叉树结构,其中每个节点的值都小于或等于其子节点的值。
  • 堆顶(即根节点)是整个堆中最小的元素。
  • 最小堆通常用于实现优先队列,因为它可以在 O(log n) 时间内插入和删除元素,并且可以在 O(1) 时间内访问最小元素。

我们的目标是将这三个链表合并成一个升序链表。为了实现这一点,我们可以使用最小堆来高效地找到当前所有链表中值最小的节点。

初始状态

在开始时,我们将每个链表的头节点加入最小堆。此时,最小堆的状态如下:

  • 堆顶 是 1,它来自链表 1 或链表 2(因为我们有两个 1)。
  • 堆的其他节点分别是链表 2 的头节点 1 和链表 3 的头节点 2
第一步:取出堆顶元素

我们从堆中取出最小的元素 1(来自链表 1),并将其加入结果链表。然后,我们将链表 1 的下一个节点 4 加入堆中。此时,堆的状态变为:

  • 堆顶 现在是 1,它来自链表 2。
  • 堆的其他节点分别是链表 1 的下一个节点 4 和链表 3 的头节点 2
第二步:再次取出堆顶元素

我们从堆中取出最小的元素 1(来自链表 2),并将其加入结果链表。然后,我们将链表 2 的下一个节点 3 加入堆中。此时,堆的状态变为:

  • 堆顶 现在是 2,它来自链表 3。
  • 堆的其他节点分别是链表 1 的下一个节点 4 和链表 2 的下一个节点 3
第三步:继续取出堆顶元素

我们从堆中取出最小的元素 2(来自链表 3),并将其加入结果链表。然后,我们将链表 3 的下一个节点 6 加入堆中。此时,堆的状态变为:

  • 堆顶 现在是 3,它来自链表 2。
  • 堆的其他节点分别是链表 1 的下一个节点 4 和链表 3 的下一个节点 6
第四步:继续取出堆顶元素

我们从堆中取出最小的元素 3(来自链表 2),并将其加入结果链表。然后,我们将链表 2 的下一个节点 4 加入堆中。此时,堆的状态变为:

  • 堆顶 现在是 4,它来自链表 1。
  • 堆的其他节点分别是链表 2 的下一个节点 4 和链表 3 的下一个节点 6
第五步:继续取出堆顶元素

我们从堆中取出最小的元素 4(来自链表 1),并将其加入结果链表。堆的状态变为:

  • 堆顶 现在是 4,它来自链表 2。
  • 堆的其他节点是链表1的下一节点5,链表 3 的下一个节点 6
第六步:继续取出堆顶元素

我们从堆中取出最小的元素 4(来自链表 2),并将其加入结果链表。此时,链表 2 已经遍历完毕,没有更多的节点可以加入堆中。

堆的状态变为:堆顶 现在是 5,它来自链表 1,其他节点是6来自链表3。

第七步:继续取出堆顶元素

我们从堆中取出元素 5,并将其加入结果链表。

第八步:继续取出堆顶元素

我们从堆中取出元素 6,并将其加入结果链表。

最终结果

合并后的链表为:1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6

时间复杂度分析

初始化最小堆
  • 操作:将 k 个链表的头节点插入最小堆。
  • 复杂度:每次插入操作的时间复杂度是 O(log⁡k),因此初始化堆的时间复杂度为 O(klog⁡k)。
提取最小元素和插入新元素
  • 操作:每次从堆中提取最小元素并插入新的节点。
  • 复杂度:每次提取最小元素和插入新元素的操作时间复杂度均为 O(log⁡k)。
  • 次数:总共需要进行 N 次提取和插入操作(因为总共有 N 个节点)。
  • 总复杂度:O(Nlog⁡k)

总时间复杂度

  • 初始化堆:O(klog⁡k)
  • 提取和插入操作:O(Nlog⁡k)

因此,总的时间复杂度为: O(klog⁡k+Nlog⁡k)

由于 klog⁡k在大多数情况下远小于 Nlog⁡k,通常可以简化为: O(Nlog⁡k)

空间复杂度分析

  • 最小堆:堆中最多包含 k 个节点(即每个链表的当前最小节点)。
  • 结果链表:需要额外的空间来存储合并后的链表,但这是输出的一部分,不计入额外空间复杂度。

因此,空间复杂度主要由最小堆决定,为: O(k)

总结

  • 时间复杂度:O(Nlog⁡k)
  • 空间复杂度:O(k)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

minGW安装教程

一、下载 1.通过官网WinGW官网下载 http://www.mingw-w64.org 2.通过SourceForge网站下载MinGW https://sourceforge.net/projects/mingw/files/latest/download 二、安装 右键mingw-get-setup.exe&#xff0c;以管理员身份运行 点击Install安装 点击“Change”修改安装地…

BFS入门

目录 定义二叉树层次遍历电梯问题倒可乐BFS基本思想算法 四方访问 定义 BFS 通常是指广度优先搜索&#xff08;Breadth - First Search&#xff09;&#xff0c;它是一种图形数据结构的遍历算法。从给定的起始顶点开始&#xff0c;首先访问起始顶点的所有邻接顶点&#xff0c;然…

如何将CSDN的文章保存为PDF?

目录 1、打开CSDN文章2、按F12或者鼠标右键选择检查并进入控制台3、在控制台输入以下代码4、然后回车&#xff08;Enter&#xff09;如果纵向显示不全就横向 1、打开CSDN文章 2、按F12或者鼠标右键选择检查并进入控制台 3、在控制台输入以下代码 (function(){ $("#side&q…

25考研软件工程 西南大学跟重庆大学哪个难?

需知晓&#xff0c;西南大学每年报考人数众多&#xff0c;可这不代表报考软件工程专业的人数就多呀&#xff0c;况且西南大学的优势学科并非工科&#xff0c;故而软件工程的报考热度不会如题主所言那般高呢。 其次得明白&#xff0c;软件工程专业上岸难度方面&#xff0c;重庆大…

普通算法——二维前缀和

二维前缀和 题目链接&#xff1a;https://www.acwing.com/problem/content/798/ 题目描述&#xff1a; 输入一个 n n n 行 m m m 列的整数矩阵&#xff0c;再输入 q q q 个询问&#xff0c;每个询问包含四个整数 ** x 1 , y 1 , x 2 , y 2 x1,y1,x2,y2 x1,y1,x2,y2 &…

Mock神器:Easy-Mock 私有化部署及使用介绍

在现代前后端分离的开发模式中&#xff0c;后端接口的数据模拟是一个常见且必要的需求。尤其是在后端接口尚未开发完成时&#xff0c;前端开发需要依赖模拟数据进行开发与测试。Easy-Mock 是一个非常流行的开源工具&#xff08;虽然它已经停止更新好长时间了&#xff09;&#…

Java的Mvc整合Swagger的knife4框架

Swagger的介绍 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。使用Swagger&#xff0c;就是把相关的信息存储在它定义的描述文件里面&#xff08;yml或json格式&#xff09;&#xff0c;再通过维护这个描述 文件可以去更…

01_Node.js入门 (黑马)

01_Node.js入门 知识点自测 从 index.js 出发&#xff0c;访问到 student/data.json 的相对路径如何写? A&#xff1a;../public/teacher/data.json B&#xff1a;./public/student/data.json C&#xff1a;../student/data.json <details><summary>答案</sum…

2024.12.5——攻防世界Training-WWW-Robots攻防世界baby_web

2024.12.5—攻防世界Training-WWW-Robots 知识点&#xff1a;robots协议 dirsearch工具 本题与第一道Robots协议十分类似&#xff0c;不做wp解析 大致步骤&#xff1a; step 1 打开靶机&#xff0c;发现是robots协议相关 step 2 用dirsearch进行扫描目录 step 3 url传参r…

电脑无法识别usb设备怎么办?电脑无法识别usb解决方法

usb设备是我们常解除的外部操作以及存储设备&#xff0c;它可以方便用户数据传输以及操作输入。但在使用过程中&#xff0c;大家基本都碰到过电脑无法识别usb设备这种情况。这种情况下&#xff0c;我们应该怎么办呢&#xff1f;下面将为你介绍几种可能的原因和解决方法&#xf…

【学习总结|DAY014】Java面向对象高级-继承、多态

一、继承&#xff08;Inheritance&#xff09; 1. 概述 继承是面向对象编程的一种特性&#xff0c;允许我们定义一个类&#xff08;称为子类或派生类&#xff09;以继承另一个类&#xff08;称为超类或基类&#xff09;的功能。 2. 语法格式 public class Zi extends Fu {/…

筑起厂区安全--叉车安全防护装置全解析

在繁忙的工业生产领域中&#xff0c;叉车作为搬运工&#xff0c;穿梭于仓储与生产线之间。然而&#xff0c;叉车的高效运作背后&#xff0c;也隐藏着诸多安全风险&#xff0c;尤其是在那些空间狭小、物流繁忙的环境中。为了降低这些潜在的危险&#xff0c;叉车安全防护装置便成…

MS SQL SERVER服务自动停止解决

报错原因 电脑异常重启&#xff0c;导致 MS SQL server 服务启动后自动停止&#xff0c;在【计算机管理】-【事件查看器】-【windows日志】中进行查看系统错误日志&#xff0c;在【应用程序】下发现可能的错误信息&#xff1a; 传递给数据库 ‘model’ 中的日志扫描操作的日志…

网络安全信息收集(总结)更新

目录 重点&#xff1a; 前言&#xff1a; 又学到了&#xff0c;就是我们什么时候要子域名收集&#xff0c;什么时候收集域名&#xff0c;重点应该放前面 思考&#xff1a; 信息收集分为哪几类&#xff0c;什么是主域名&#xff0c;为什么要收集主域名&#xff0c;为什么要收…

使用 Postman 上传二进制类型的图片到后端接口写法

我们有的时候会有需求&#xff0c;就是通过 postman 传递二进制图片到后端接口&#xff0c;如下图&#xff1a; 那我们的 Java 接口需要怎么写呢&#xff1f; Spring Boot 接收这些数据的方式需要使用 RequestBody 注解来处理原始的二进制数据&#xff08;byte[]&#xff09;。…

Java Web 7 请求响应(Postman)

前言&#xff08;SpringBoot程序请求响应流程&#xff09; 以上一章的程序为例&#xff0c;一个基于SpringBoot的方式开发一个web应用&#xff0c;浏览器发起请求 /hello 后 &#xff0c;给浏览器返回字符串 “Hello World ~”。 而我们在开发web程序时呢&#xff0c;定义了一…

pytorch多GPU训练教程

pytorch多GPU训练教程 文章目录 pytorch多GPU训练教程1. Torch 的两种并行化模型封装1.1 DataParallel1.2 DistributedDataParallel 2. 多GPU训练的三种架构组织方式2.2 数据不拆分&#xff0c;模型拆分&#xff08;Model Parallelism&#xff09;2.3 数据拆分&#xff0c;模型…

【opencv入门教程】9.视频加载

文章选自&#xff1a; 一、VideoCapture类 用于从视频文件、图像序列或摄像头捕获视频的类。函数&#xff1a;CV_WRAP VideoCapture();brief 默认构造函数CV_WRAP explicit VideoCapture(const String& filename, int apiPreference CAP_ANY);brief 使用 API 首选项打开…

海外的bug-hunters,不一样的403bypass

一种绕过403的新技术&#xff0c;跟大家分享一下。研究HTTP协议已经有一段时间了。发现HTTP协议的1.0版本可以绕过403。于是开始对lyncdiscover.microsoft.com域做FUZZ并且发现了几个403Forbidden的文件。 &#xff08;访问fsip.svc为403&#xff09; 在经过尝试后&#xff0…

阿里内部正式开源“Spring Cloud Alibaba (全彩小册)”

年轻的毕业生们满怀希望与忐忑&#xff0c;去寻找、竞争一个工作机会。已经在职的开发同学&#xff0c;也想通过社会招聘或者内推的时机争取到更好的待遇、更大的平台。 然而&#xff0c;面试人群众多&#xff0c;技术市场却相对冷淡&#xff0c;面试的同学们不得不面临着 1 个…