LeetCode题练习与总结:合并K个升序链表

一、题目

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

二、解题思路

  1. 创建一个最小堆(优先队列)来存储所有链表的头节点。这样我们可以始终取出当前所有链表中值最小的节点。
  2. 初始化一个虚拟头节点(dummy),它将作为合并后链表的头节点。
  3. 创建一个指针(current)指向虚拟头节点,用于构建新的链表。
  4. 循环执行以下步骤直到所有链表都被合并: a. 从最小堆中取出最小节点。 b. 将current指针移动到这个最小节点。 c. 将最小节点的next指针指向最小堆中的下一个最小节点,或者如果当前链表已经没有更多节点,则指向null。 d. 将取出的节点的原链表的下一个节点加入到最小堆中,以便后续处理。
  5. 当所有链表都合并完毕,current指针将指向合并后链表的尾节点。返回虚拟头节点的下一个节点即为合并后的链表。

三、具体代码

import java.util.PriorityQueue;class Solution {public ListNode mergeKLists(ListNode[] lists) {// 创建一个最小堆来存储链表头节点PriorityQueue<ListNode> minHeap = new PriorityQueue<>((a, b) -> a.val - b.val);// 初始化虚拟头节点ListNode dummy = new ListNode(0);ListNode current = dummy;// 初始化最小堆for (ListNode list : lists) {if (list != null) {minHeap.offer(list);}}// 开始合并链表while (!minHeap.isEmpty()) {// 取出最小节点ListNode minNode = minHeap.poll();// 将current指向这个最小节点current.next = minNode;// 移动current指针current = current.next;// 如果还有下一个节点,加入到最小堆中if (minNode.next != null) {minHeap.offer(minNode.next);}}// 返回合并后的链表头节点return dummy.next;}
}// ListNode的定义已经在问题描述中给出

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 时间复杂度是O(NlogK)。

  • 初始化最小堆的时间复杂度是O(N),其中N是所有链表中元素的总数。这是因为我们需要遍历每个链表的头节点,并将它们加入到最小堆中。对于每个节点,最小堆的插入操作是O(logK),K是链表的数量。但是,由于每个节点最多被插入一次,所以这部分的总时间复杂度是O(N)。

  • 合并链表的循环中,我们从最小堆中取出节点,这个操作是O(logK)。然后,我们将取出的节点的下一个节点(如果有的话)再次加入到最小堆中,这个操作同样是O(logK)。这个循环会执行N次,因为我们需要处理所有N个元素。所以,这部分的总时间复杂度是O(NlogK)。

2. 空间复杂度
  • 空间复杂度是O(K)。

  • 最小堆存储了所有链表的头节点,最多时有K个节点,所以空间复杂度是O(K)。

  • 合并后的链表不需要额外的空间,因为它是直接在原有链表的基础上构建的。

  • 虚拟头节点dummy是一个常数级别的空间开销。

请注意,这里的K是链表的数量,而不是链表的长度。在实际应用中,如果链表数量远小于链表长度,那么K可能会比N小得多,这样时间复杂度和空间复杂度都会相对较低。

五、总结知识点

  1. 链表(Linked List):代码中使用了单向链表的数据结构,每个ListNode包含一个值(val)和一个指向下一个节点的指针(next)。

  2. 优先队列(PriorityQueue):为了有效地合并多个已排序的链表,代码使用了Java的PriorityQueue,它是一个基于优先级堆(通常是最小堆)的无界队列。在这个场景中,它被用来存储所有链表的头节点,以便快速取出当前最小的节点。

  3. 比较器(Comparator):在创建PriorityQueue时,使用了自定义的比较器来定义节点之间的排序规则。这里通过比较节点的值(val)来实现升序排列。

  4. 虚拟头节点(Dummy Node):为了避免在合并链表时处理特殊情况(如空链表),代码中创建了一个虚拟头节点dummy。这样可以简化代码逻辑,因为始终有一个有效的current节点可以连接新的节点。

  5. 循环和条件判断:在合并链表的循环中,使用了while循环和if条件判断来控制流程,确保在每次迭代中都取出最小节点,并将其正确地连接到合并后的链表中。

  6. 指针操作:在链表操作中,current指针被用来遍历和构建新的链表。每次循环中,current都会移动到新添加的节点,以便为下一个节点的添加做准备。

  7. 返回值:最终,函数返回虚拟头节点的下一个节点,即合并后链表的实际头节点。这是链表操作中常见的技巧,用于简化边界条件的处理。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

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

相关文章

人工智能指数报告2023

人工智能指数报告2023 主要要点第 1 章 研究与开发第 2 章 技术性能第 3 章 人工智能技术伦理第 4 章 经济第 5 章 教育第 6 章 政策与治理第 7 章 多样性第 8 章 舆论 人工智能指数是斯坦福大学以人为本的人工智能研究所&#xff08;HAI&#xff09;的一项独立倡议&#xff0c…

Java 石头剪刀布小游戏

一、任务 编写一个剪刀石头布游戏的程序。程序启动后会随机生成1~3的随机数&#xff0c;分别代表剪刀、石头和布&#xff0c;玩家通过键盘输入剪刀、石头和布与电脑进行5轮的游戏&#xff0c;赢的次数多的一方为赢家。若五局皆为平局&#xff0c;则最终结果判为平局。 二、实…

redis 为什么会阻塞

目录 前言 客户端交换时的阻塞 redis 磁盘交换的阻塞 主从节点交互的阻塞 切片集群交互时的阻塞 异步执行的演变 redis 异步执行如何实现的 前言 大家对redis 比较熟悉吧&#xff0c;只要做项目都会用到redis&#xff0c;提高系统的吞吐。小米商城抢购高峰18k的qps&…

KubeSphere平台安装系列之三【Linux多节点部署KubeSphere】(3/3)

**《KubeSphere平台安装系列》** 【Kubernetes上安装KubeSphere&#xff08;亲测–实操完整版&#xff09;】&#xff08;1/3&#xff09; 【Linux单节点部署KubeSphere】&#xff08;2/3&#xff09; 【Linux多节点部署KubeSphere】&#xff08;3/3&#xff09; **《KubeS…

一句话讲清楚数据库中事务的隔离级别(通俗易懂版)

为什么我只说通俗易懂版不说严谨版? 因为严谨版遍地都是, 但是他们却有一个缺点就是让人看得云里雾里, 所以这就是我写通俗易懂版的初衷! 但是既然是通俗易懂版就必然有缺陷, 只为了各位在开发过程中头脑更加清晰, 如有错误还望兄弟们不吝赐教! 在MySQL数据库中,事务一共有4…

C语言之strcmp函数,strlen函数

strcmp函数是比较两个字符串ASCII大小的函数。 比较方式是自左向右比较&#xff0c;直到出现不同字符或者\0为止 语法格式 strcmp(字符串1,字符串2&#xff09; 如果两个字符串相同&#xff0c;会返回数值0 如果字符串1>字符串2,会返回一个正数 如果字符串1<字符串2…

新一代电话机器人开源PHP源代码

使用easyswoole 框架开发的 新一代电话机器人开源PHP源码 项目地址&#xff1a;https://gitee.com/ddrjcode/robotphp 代理商页面演示地址 http://119.23.229.15:8080 用户名&#xff1a;c0508 密码&#xff1a;123456 包含 AI外呼管理&#xff0c;话术管理&#xff0c;CR…

每日一题 — 复写零

1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 首先找到最后一个复写的数&#xff1a; 双指针算法&#xff1a; 1、先判断 cur 位置上的值 2、然后决定 dest 移动一步还是两步 3、然后判断 dest 是否到终点了 4、最后 cur 处理越界的情况 arr[n-1] …

使用sourceCompatibility = 11不匹配解决方法

运行springbootgradle项目报错。 原因&#xff1a;在生产该项目时&#xff0c;选择的JDK是11版本的&#xff0c;但是本地电脑只安装了1.8版本。不兼容所以报错。 解决办法&#xff1a; 找到build.gradle配置文件—>找到sourceCompatibility ‘11’—>把11改成自己本地…

思维题(蓝桥杯 填空题 C++)

目录 题目一&#xff1a; ​编辑 代码&#xff1a; 题目二&#xff1a; 代码&#xff1a; 题目三&#xff1a; 代码&#xff1a; 题目四&#xff1a; 代码&#xff1a; 题目五&#xff1a; 代码&#xff1a; 题目六&#xff1a; 代码七&#xff1a; 题目八&#x…

用python和pygame库实现刮刮乐游戏

用python和pygame库实现刮刮乐游戏 首先&#xff0c;确保你已经安装了pygame库。如果没有安装&#xff0c;可以通过以下命令安装&#xff1a; pip install pygame 示例有两个。 一、简单刮刮乐游戏 准备两张图片&#xff0c;一张作为背景bottom_image.png&#xff0c;一张作…

Leetcoder Day35| 动态规划part02

62.不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff…

如何在Linux配置C、C++、Go语言的编译环境?

在 Linux 系统上配置 C、C、Go 语言的编译环境可以通过安装相应的编译器和相关工具来实现。以下是在 Linux 系统上配置这些语言的编译环境的一般步骤&#xff1a; 1. C 和 C 编译环境配置&#xff1a; 安装 GCC 编译器&#xff08;一般 Linux 发行版都会包含&#xff09;&…

Android 显示系统框架

一.FrameBuffer FrameBuffer 介绍&#xff1a; FrameBuffer中文译名为帧缓冲驱动&#xff0c;它是出现在2.2.xx内核中的一种驱动程序接口。主设备号为29&#xff0c;次设备号递增。 Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。FrameBuffer机制模仿显卡的功能…

Day11:信息打点-Web应用企业产权指纹识别域名资产网络空间威胁情报

目录 Web信息收集工具 业务资产-应用类型分类 Web单域名获取-接口查询 Web子域名获取-解析枚举 Web架构资产-平台指纹识别 思维导图 章节知识点&#xff1a; Web&#xff1a;语言/CMS/中间件/数据库/系统/WAF等 系统&#xff1a;操作系统/端口服务/网络环境/防火墙等 应用…

dart中的事件队列与微任务

dart在每个事件循环中&#xff0c;会先执行同步任务代码&#xff0c;然后分别检查两个任务队列&#xff1a;微任务队列和事件队列。dart总是先执行微任务队列中的代码&#xff0c;然后才是事件队列中的代码。当两个队列中的任务都执行完成后&#xff0c;线程进入休眠状态&#…

Stable Diffusion WebUI API http://127.0.0.1:7860/docs空白

在尝试调用Stable Diffusion WebUI API的时候&#xff0c;打开http://127.0.0.1:7860/docs遇到了以下页面 网络诊断是这样的原因&#xff1a; 修bug&#xff0c;改来改去遇到了以下两种页面&#xff1a; 此时http://127.0.0.1:7860可以如下正常显示&#xff1a; 查资料的时候找…

vue+springboot项目部署服务器

项目仓库&#xff1a;vuespringboot-demo: vuespringboot增删改查的demo (gitee.com) ①vue中修改配置 在public文件夹下新建config.json文件&#xff1a; {"serverUrl": "http://localhost:9090"//这里localhost在打包后记得修改为服务器公网ip } 然后…

[NSSCTF 2nd] web复现

1.php签到 <?phpfunction waf($filename){$black_list array("ph", "htaccess", "ini");$ext pathinfo($filename, PATHINFO_EXTENSION);foreach ($black_list as $value) {if (stristr($ext, $value)){return false;}}return true; }if(i…

nginx 配置浏览器不缓存文件 每次都会从服务器 请求新的文件

目录 解决问题方法说明 测试html环境js环境第一步然后修改内容 打开带有js缓存的页面强制刷新 配置nginx 每次打开页面都会重新请求index.js 文件重启nginx再次修改index.js 总结设置为全局 解决问题 适用于实时更新数据的&#xff0c;网页 可以让用户每次都是重新请求&#x…