数据结构与算法之堆: Leetcode 23. 合并 K 个升序链表 (Typescript版)
合并 K 个升序链表
- https://leetcode.cn/problems/merge-k-sorted-lists/
描述
- 给你一个链表数组,每个链表都已经按升序排列
- 请你将所有链表合并到一个升序链表中,返回合并后的链表
示例 1
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[1->4->5,1->3->4,2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2
输入:lists = []
输出:[]
示例 3
输入:lists = [[]]
输出:[]
提示
- k == lists.length
- 0 <= k <= 1 0 4 10^4 104
- 0 <= lists[i].length <= 500
- - 1 0 4 10^4 104 <= lists[i][j] <= 1 0 4 10^4 104
- lists[i] 按 升序 排列
- lists[i].length 的总和不超过 1 0 4 10^4 104
算法实现
1 )使用堆
/*** Definition for singly-linked list.* class ListNode {* val: number* next: ListNode | null* constructor(val?: number, next?: ListNode | null) {* this.val = (val===undefined ? 0 : val)* this.next = (next===undefined ? null : next)* }* }*/class MinHeap {heap: Array<ListNode | null> = [];// 交换节点位置swap(i1, i2) {[this.heap[i1], this.heap[i2]] = [this.heap[i2], this.heap[i1]];}// 获得父节点getParentIndex(i) {return (i - 1) >> 1;}// 获取左子节点getLeftIndex(i) {return (i << 1) + 1; // 极客写法}// 获取右子节点getRightIndex(i) {return (i << 1) + 2;}// 上移操作封装 是个递归shiftUp(i) {// 如果到了堆顶元素,index是0,则不要再上移了if(!i) return;// 获得父节点下标: piconst pi = this.getParentIndex(i);// 开始做比较if(this.heap[pi]?.val > this.heap[i].val) {// 实现交换this.swap(pi, i);// 继续尝试上移操作this.shiftUp(pi);}}// 下移操作shiftDown(i) {// 如果到了堆尾元素,则不要再下移了if(i >= this.heap.length - 1) return;let li = this.getLeftIndex(i); // 左孩子索引let ri = this.getRightIndex(i); // 右孩子索引// 左孩子节点的值 < 当前节点的值if(this.heap[li]?.val < this.heap[i].val) {this.swap(li, i);this.shiftDown(li);}// 同样,对右孩子节点的值 < 当前节点的值if(this.heap[ri]?.val < this.heap[i].val) {this.swap(ri, i);this.shiftDown(ri);}}// 插入insert(value) {this.heap.push(value);this.shiftUp(this.heap.length - 1);}// 删除堆顶pop() {if(this.size() === 1) return this.heap.shift();let top = this.heap[0];// 变相删除堆顶, 堆尾元素移动到堆顶this.heap[0] = this.heap.pop(); // 删除数组的最后一个元素并返回,返回值赋值给堆顶元素// 执行堆顶下移操作,维持堆的有序性this.shiftDown(0);return top;}// 获取堆顶peak() {return this.heap[0];}// 获取堆的大小size() {return this.heap.length;}
}function mergeKLists(lists: Array<ListNode | null>): ListNode | null {let res = new ListNode(0);let p = res;const h = new MinHeap();// 通过输入来构建堆结构// 三个链表,堆中存入的是三个链表的头lists.forEach(l => {l && h.insert(l); // l是个链表,其实用的是链表头表示,也就是链表的第一个元素})// while循环,每一轮pk的都是堆内的元素// 谁出队,就把谁的下一个入堆,逐个比较// 最终堆空了,比较全部结束while(h.size()) {let n = h.pop(); // 弹出堆顶元素,最小值p.next = n; // 将堆顶元素挂载在新链表上p = p.next; // 链表指针移位,为下次连接做准备n.next && h.insert(n.next) // 将弹出的堆顶元素的下一个元素入堆,进行重新构建堆结构}return res.next; // 返回的是next, 因为其第一个节点是我们new出来,用于连接的,所以不包含第一个节点
}
- 时间复杂度 O(nlogk)
- forEach O(k), k是链表数量
- while循环遍历了所有链表的所有节点 O(n),n是所有链表节点之和
- 并且堆操作是O(logk), 两者结合:O(nlogk)
- 整体:O(nlogk)
- 空间复杂度 O(k)
- 就是堆的大小
- 堆能高效、快速找出最大值和最小值,时间复杂度O(1),堆顶是最大值或最小值
- 找出第K个最大(小)元素
- 构建一个容量为k的堆,让每个元素都插入这个堆
- 保持容量始终为k, 最终堆顶就是最大元素或最小元素
- 这个解法不算精妙,但是是两个数据结构(堆和链表)融合解题的典型
相关文章:
数据结构与算法之堆: Leetcode 23. 合并 K 个升序链表 (Typescript版)
合并 K 个升序链表 https://leetcode.cn/problems/merge-k-sorted-lists/ 描述 给你一个链表数组,每个链表都已经按升序排列请你将所有链表合并到一个升序链表中,返回合并后的链表 示例 1 输入:lists [[1,4,5],[1,3,4],[2,6]] 输出&…...
代码随想录算法训练营第五十七天 | 392.判断子序列 115.不同的子序列
1. 判断子序列 392. 判断子序列 - 力扣(LeetCode) dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度。 class Solution {public boolean isSubsequence(String s, String t) {//dp[i][j] 表示…...
Kafka日志索引详解以及生产常见问题分析与总结
文章目录 1、Kafka的Log日志梳理1.1、Topic下的消息是如何存储的?1.1.1、 log文件追加记录所有消息1.1.2、 index和timeindex加速读取log消息日志。 1.2、文件清理机制1.2.1、如何判断哪些日志文件过期了1.2.2、过期的日志文件如何处理 1.3、Kafka的文件高效读写机制…...
vue中 css scoped原理
Vue中css的逻辑是先放子组件,然后放父组件,所以同样的css类名,子组件会被父组件覆盖 html 如下 子被父覆盖 scoped是通过给组件加hash值,锁定组件。 父子组件均scoped的情况下,子仍会覆盖 还是被覆盖了 如何避免被…...
tf.compat.v1.global_variables()
tf.global_variables tf.global_variables() 是 TensorFlow 1.x 中的一个函数,它返回图中所有的全局变量。在 TensorFlow 2.x 中,这个函数已经被移除了,取而代之的是 tf.compat.v1.global_variables()。 然而,在 TensorFlow 2.x …...
登录注册实现
一、前端页面注册到Vue 1.创建登录和注册组件 <template><div>login</div></template><script> export default {name: HomeView,data() {return {}},methods: {}, } </script><template><div>register</div></tem…...
Push rejected: Push to origin/master was rejected
Push rejected: Push to origin/master was rejected 原因:推拒绝:推送到起源/主人被拒绝 解决方案如下: 方案1: 1.在Idea打开终端 方案2: 1、在对应项目文件里打开 Git Bash 然后依次输入: git pull …...
在线OJ项目核心思路
文章目录 在线OJ项目核心思路1. 项目介绍2.预备知识理解多进程编程为啥采用多进程而不使用多线程?标准输入&标准输出&标准错误 3.项目实现题目API实现相关实体类定义新增/修改题目获取题目列表 编译运行编译运行流程 4.统一功能处理 在线OJ项目核心思路 1. 项目介绍 …...
Spring MVC:数据绑定
Spring MVC 数据绑定数据类型转换数据格式化数据校验 附 数据绑定 数据绑定,指 Web 页面上请求和响应的数据与 Controller 中对应处理方法上的对象绑定(即是将用户提交的表单数据绑定到 Java 对象中)。 过程如下: ServletRequest…...
STM32CubeMX学习笔记-USB接口使用(HID按键)
STM32CubeMX学习笔记-USB接口使用(HID按键) 一、USB简介1.1 USB HID简介 二、新建工程1. 打开 STM32CubeMX 软件,点击“新建工程”2. 选择 MCU 和封装3. 配置时钟4. 配置调试模式 三、USB3.1 参数配置3.2 引脚配置3.3 配置时钟3.4 USB Device…...
C#,数值计算——Ranq2的计算方法与源程序
1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Backup generator if Ranq1 has too short a period and Ran is too slow.The /// period is 8.5E37. Calling conventions same as Ran, above. /// </summary> …...
C/C++ 数据结构 - 链表
1.单链表 https://blog.csdn.net/qq_36806987/article/details/79858957 1 #include<stdio.h>2 #include<stdlib.h>3 4 /*结构体部分*/5 typedef struct Node6 {7 int data; //数值域8 struct Node *next; //指针域9 }N;10 11 N *Init() //初始化单…...
【算法基础】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序
目录 1 冒泡排序(Bubble Sort) 2 插入排序(Insertion Sort) 3 选择排序(Selection Sort) 4. 快速排序(Quick Sort) 5. 归并排序(Merge Sort) 6 堆排序 …...
javascript二维数组(3):指定数组元素的特定属性进行搜索
js中对数组, var data [{“name”: “《西游记》”, “author”: “吴承恩”, “cat”: “A级书刊”, “num”: 3},{“name”: “《三国演义》”, “author”: “罗贯中”, “cat”: “A级书刊”, “num”: 8},{“name”: “《红楼梦》”, “author”: “曹雪芹”,…...
使用Qt进行HTTP通信的方法
文章目录 1 HTTP协议简介1.1 HTTP协议的历史和发展1.2 HTTP协议的特点1.3 HTTP的工作过程1.4 请求报文1.5 响应报文 2 使用Qt进行HTTP通信2.1 Qt的HTTP通信类2.2 HTTP通信过程 3 JSON3.1 cJSON库简介3.2 cJSON库的设计思想和数据结构3.3 cJSON库的使用方法 1 HTTP协议简介 1.1…...
第45节——页面中修改redux里的数据
一、什么是action 在 Redux 中,Action 是一个简单的 JavaScript 对象,用于描述对应应用中的某个事件(例如用户操作)所发生的变化。它包含了一个 type 属性,用于表示事件的类型,以及其他一些可选的数据。 …...
软考 系统架构设计师系列知识点之软件架构风格(2)
接前一篇文章:软考 系统架构设计师系列知识点之软件架构风格(1) 这个十一注定是一个不能放松、保持“紧”的十一。由于报名了全国计算机技术与软件专业技术资格(水平)考试,11月4号就要考试,因此…...
【C++11】Lambda 表达式:基本使用 和 底层原理
文章目录 Lambda 表达式1. 不考虑捕捉列表1.1 简单使用介绍1.2 简单使用举例 2. 捕捉列表 [ ] 和 mutable 关键字2.1 使用方法传值捕捉传引用捕捉 2.2 捕捉方法一览2.3 使用举例 3. lambda 的底层分析 Lambda 表达式 书写格式: [capture_list](parameters) mutabl…...
【网络安全---ICMP报文分析】Wireshark教程----Wireshark 分析ICMP报文数据试验
一,试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机(虚拟机) kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置: 编辑-------- 虚拟网路编辑器 更改设置进来以后 ,先选择N…...
【Docker】Docker的应用包含Sandbox、PaaS、Open Solution以及IT运维概念的详细讲解
前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...
曲轴基于灵敏度的拓扑优化-CAE操作过程
前言 本示例展示了曲轴基于灵敏度的拓扑优化的基本工作流程。 该模型为简化曲轴模型,设计区域采用壳单元建模,轴体部分采用梁单元建模,壳单元与梁单元之间通过 RBE2 多点约束单元 进行耦合连接。 本次优化的目标是通过体积最小化实现曲轴的轻…...
3PEAK思瑞浦 TP2262-TSR TSSOP8 运算放大器
特性 供电电压:3V至36V 低供电电流:每通道最大1000A差分输入电压范围至电源轨,可作为比较器工作 输入轨至-Vs,轨到轨输出快速响应:3.5MHz带宽,15V/us斜率,100ns过载恢复时间 低失调电压:-25C时最大2mV-2.5 mV在-40C至85C(最大) -3…...
开源数字白板the-board:基于React+Fabric.js的实时协作技术解析
1. 项目概述:一个开源的“数字白板”能做什么?最近在GitHub上看到一个挺有意思的项目,叫the-board。乍一看名字,可能觉得平平无奇,但点进去你会发现,它其实是一个功能相当完整的在线白板应用。简单来说&…...
windows系统安装wsl安装opencode教程
使用 AI 助手(OpenCode)在 WSL2 中高效安全工作教程 背景 在 AI 极大发展的现在,AI 可以帮助我们完成很多工作。那么怎么让 AI 帮我们高效、安全地工作呢?以下是教程。 同时,大模型在 Windows 里面直接执行脚本时错…...
35岁程序员的AI转型之路:年薪翻倍,收藏这份从零到架构师的详细指南
本文分享了作者作为35岁Java程序员的AI转型经历,从初期的焦虑与迷茫,到通过学习ChatGPT、Prompt Engineering和大模型技术,最终成功转型为AI架构师的故事。文章详细描述了学习路径、关键决策、遇到的坑以及成功因素,并给其他程序员…...
从业者必看:医药资质认证服务核心知识梳理
如果你是初创医疗器械贸易商创始人、医美诊所创业者、连锁药店负责人或是医药电商运营人员,正面临缺证无法入驻平台、自行办理流程繁琐反复被驳回、赶大促节点急需下证等问题,想要了解医药资质认证服务相关内容,这篇科普内容会为你梳理清楚全…...
基于浏览器自动化的高级爬虫框架autoclaw实战指南
1. 项目概述与核心价值最近在折腾自动化脚本时,发现了一个挺有意思的GitHub项目,叫jmoraispk/autoclaw。乍一看名字,可能会联想到“自动爪子”或者“爬虫”,实际上,它也确实是一个专注于自动化网页交互和数据抓取的工具…...
可穿戴ESD监测:从被动防护到主动感知的静电管理革命
1. 项目概述:当静电成为“幽灵”,可穿戴监测如何为航空航天制造“显形” 在航空航天和高可靠性电子制造领域,我们常常与一个看不见的“幽灵”作斗争——静电放电。这个“幽灵”无声无息,却能轻易摧毁价值数十万甚至数百万美元的精…...
Windows 11终极优化指南:一键清理系统臃肿,免费提升51%性能
Windows 11终极优化指南:一键清理系统臃肿,免费提升51%性能 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to …...
别再硬算公式了!用Excel搞定STM32 NTC测温的ADC查表法(附完整表格)
用Excel玩转STM32 NTC测温:查表法实战指南 嵌入式开发中,温度测量是个永恒的话题。NTC热敏电阻因其成本低廉、响应迅速,成为工程师们的首选传感器。但每次项目都要重新推导温度计算公式,不仅耗时费力,还容易在数学转换…...
