数据结构与算法之堆: 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操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
