【LeetCode】23. 合并 K 个升序链表
题目链接:23. 合并 K 个升序链表
题目描述:

数据范围:

**思考:**这题实际上就是合并两个有序列表的进阶版,只不过这里变成了合并K个,那么这里我们显然就知道,核心的合并两个有序列表的思路不变,剩下的重点处理就在于如何将这K个链表进行两两合并了,方式有很多,但效率不一,下面介绍几种易想到的思路:
方法一:顺序合并
顺序合并思路很简单,就是顺序地将这K个链表两两地进行合并。
代码:
/*** Definition for singly-linked list.* type ListNode struct {* Val int* Next *ListNode* }*/
func mergeKLists(lists []*ListNode) *ListNode {if len(lists) == 0 {return new(ListNode).Next}res := lists[0]lists = lists[1:]for _,list := range lists {res = mergeTwoLists(res,list)}return res
}
// 合并两个升序链表
func mergeTwoLists(l1 ,l2 *ListNode) *ListNode {head := new(ListNode)l := headfor ;l1 != nil && l2 != nil; {if l1.Val < l2.Val {l.Next = l1l1 = l1.Next}else {l.Next = l2l2 = l2.Next}l = l.Next}if l1 != nil {l.Next = l1}if l2 != nil {l.Next = l2}return head.Next
}

方法二、分治
顺序合并的效率并不高,这样做就类似于阻塞操作,合并前面的链表的时候,无关的链表啥事儿都干不了,因此,我们可以考虑进行分治,先递归地划分区间两两合并,最后再将总的合并起来。
代码:
/*** Definition for singly-linked list.* type ListNode struct {* Val int* Next *ListNode* }*/
func mergeKLists(lists []*ListNode) *ListNode {if len(lists) == 0 {return new(ListNode).Next}return merge(0,len(lists)-1,lists)
}func merge(l,r int,lists []*ListNode) *ListNode {if l > r {return nil}if l == r {return lists[l]}mid := (l+r)>>1return mergeTwoLists(merge(l,mid,lists),merge(mid+1,r,lists))
}func mergeTwoLists(l1 ,l2 *ListNode) *ListNode {head := new(ListNode)l := headfor ;l1 != nil && l2 != nil; {if l1.Val < l2.Val {l.Next = l1l1 = l1.Next}else {l.Next = l2l2 = l2.Next}l = l.Next}if l1 != nil {l.Next = l1}if l2 != nil {l.Next = l2}return head.Next
}

方法三、小根堆
看了下题解找出了不同的写法的,基本上用了小根堆(优先队列)的结构来实现的,思路就是初始时将每个链表的头结点加入到堆中,调整成为一个小根堆,那么堆顶结点一定是最小的。循环取堆中的元素,直到堆为空,注意,每次从堆中取出一个节点就需要将该节点从堆中移除,并将这个节点的下一个节点加入到堆中。
代码:
func mergeKLists(lists []*ListNode) *ListNode {h := hp{}for _, head := range lists {if head != nil {h = append(h, head)}}heap.Init(&h) // 初始化小根堆res := &ListNode{} // 哨兵节点,作为合并后链表头节点的前一个节点cur := res // 当前合并的链表位置,也就res链表末尾for len(h) > 0 {node := heap.Pop(&h).(*ListNode) // 取出堆顶元素if node.Next != nil { // 该节点的下一个节点不空,就再加入堆中heap.Push(&h, node.Next)}cur.Next = node // 记录到答案中cur = cur.Next // 准备合并下一个节点}return res.Next
}// golang中小根堆的实现
type hp []*ListNode
func (h hp) Len() int { return len(h) }
func (h hp) Less(i, j int) bool { return h[i].Val < h[j].Val } // 最小堆
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(x interface{}) {*h = append(*h, x.(*ListNode))}
func (h *hp) Pop() interface{} {n := len(*h)ans := (*h)[n-1] // n-1个元素就是堆顶元素*h = (*h)[:n-1]return ans
}

这种做法很容易能看出复杂度为O(n*logk),其中k是链表长度,而n是所有链表节点数之和,这里logk主要是k个链表加入到堆中,所以时间复杂度为logk。
相关文章:
【LeetCode】23. 合并 K 个升序链表
题目链接:23. 合并 K 个升序链表 题目描述: 数据范围: **思考:**这题实际上就是合并两个有序列表的进阶版,只不过这里变成了合并K个,那么这里我们显然就知道,核心的合并两个有序列表的思路不…...
2023年【熔化焊接与热切割】免费试题及熔化焊接与热切割考试总结
题库来源:安全生产模拟考试一点通公众号小程序 熔化焊接与热切割免费试题参考答案及熔化焊接与热切割考试试题解析是安全生产模拟考试一点通题库老师及熔化焊接与热切割操作证已考过的学员汇总,相对有效帮助熔化焊接与热切割考试总结学员顺利通过考试。…...
为什么要学中文编程?它能有哪些益处?免费版编程工具怎么下载?系统化的编程教程课程怎么学习
一、为什么要学习这个编程工具?能给自己带来什么益处? 1、不论在哪里上班,都不是铁饭碗:现在全球经济低迷,使得很多企业倒闭, 大到知名国企小到私营企业,大量裁员。任何人都无法保证自己现在的…...
数据分析实战 - 2 订单销售数据分析(pandas 进阶)
题目来源:和鲸社区的题目推荐: 刷题源链接(用于直接fork运行 https://www.heywhale.com/mw/project/6527b5560259478972ea87ed 刷题准备 请依次运行这部分的代码(下方4个代码块),完成刷题前的数据准备 …...
测试服务器端口是否开通,计算退休时间
本案例知识点 netstat -tuln | grep 80 nestat 目前主机打开的网络服务端口,-tuln目前主机启动的服务,如图 报错说参数太多,仔细检查发现if后的中括号内,变量少双引号导致,改完之后运行显示22,25端口开放࿰…...
Prometheus接入AlterManager配置企业微信告警(基于K8S环境部署)
文章目录 一、创建企业微信机器人二、配置AlterManager告警发送至企业微信三、Prometheus接入AlterManager配置四、部署PrometheusAlterManager(放到一个Pod中)五、测试告警 注意:请基于 PrometheusGrafana监控K8S集群(基于K8S环境部署)文章之上做本次实验。 一、创…...
11.1 Linux 设备树
一、什么是设备树? 设备树(Device Tree),描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息: 树的主干就是系统总线, IIC 控制器、 GPIO 控制…...
万宾科技管网水位监测助力智慧城市的排水系统
以往如果要了解城市地下排水管网的水位变化,需要依靠人工巡检或者排查的方式,这不仅加大了人员的工作量,而且也为市政府带来了更多的工作难题。比如人员监管监测不到位或无法远程监控等情况,都会降低市政府对排水管网的管理能力&a…...
Glide transform CircleCrop()圆图,Kotlin
Glide transform CircleCrop()圆图,Kotlin import android.os.Bundle import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.load.resource.bitmap.CircleCropclass MainActivity : AppCompatActivity() {o…...
从NetSuite Payment Link杂谈财务自动化、数字化转型
最近在进行信息化的理论学习,让我有机会跳开软件功能,用更加宏大的视野,来审视我们在哪里,我们要到哪去。 在过去20多年,我们的财务软件经历了电算化、网络化、目前处于自动化、智能化阶段。从NetSuite这几年的功能发…...
1.UML面向对象类图和关系
文章目录 4种静态结构图类图类的表示类与类之间的关系依赖关系(Dependency)关联关系(Association)聚合(Aggregation)组合(Composition)实现(Realization)继承/泛化(Inheritance/Generalization)常用的UML工具reference欢迎访问个人网络日志🌹🌹知行空间🌹🌹 4种静态结构…...
JAVA小说小程序系统是怎样开发的
随着移动互联网的普及,小说阅读已经成为人们休闲娱乐的重要方式之一。为了满足广大读者的需求,我们开发了一款基于JAVA编程语言的小说小程序系统。本系统旨在提供一种便捷、高效、有趣的阅读体验,让用户能够随时随地阅读最新、最热门的小说。…...
【深度学习】pytorch——Tensor(张量)详解
笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ pytorch——Tensor 简介创建Tensortorch.Tensor( )和torch.tensor( )的区别torch.Tensor( )torch.tensor( ) tensor可以是一个数(标量)、一维数组(向量)、二维数组&…...
装修服务预约小程序的内容如何
大小装修不断,市场中大小品牌也比较多,对需求客户来说,可以线下咨询也可以线上寻找品牌,总是可以找到满意的服务公司,而对装修公司来说如今线下流量匮乏,很多东西也难以通过线下方式承载,更需要…...
easypoi 导出Excel 使用总结
easypoi 导出Excel 导出Excel需要设置标题,且标题是多行,标题下面是列表头 设置表格标题 ExportParams headExportParams new ExportParams();StringBuilder buffer new StringBuilder("");buffer.append("1、课程名称:....…...
MySQL性能优化的最佳20条经验
概述 关于数据库的性能,这并不只是DBA才需要担心的事。当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能。下面讲下MySQL性能优化的一些点。 1. 为查询缓存优化你的查询 大多数的MySQL服务器…...
【Liunx基础】之指令(一)
【Liunx基础】之指令(一) 1.ls指令2.pwd命令3.cd指令4.touch指令5.mkdir指令(重要)6.rmdir指令与rm指令(重要)7.man指令(重要)8.cp指令(重要) 📃博客主页: 小…...
jQuery案例专题
jQuery案例专题 本学期主要担任的课程是js和jQuery,感觉用到的有一些案例挺有意思的,就对其进行了一下整理。 目录: 电影院的幕帘特效 手风琴特效 星光闪烁 网页轮播图 1.电影院的幕帘特效代码如下 html <!DOCTYPE html > <html…...
【Linux】服务器间免登陆访问
准备两台服务器,服务器A,服务器B 在服务器A中实现免登陆服务器B 进入服务器A操作 进入目录/root/.ssh cd /root/.ssh秘钥对使用默认文件名 生成秘钥对,在输入秘钥文件时直接回车则会使用默认文件名:id_rsa ssh-keygen -t rsa…...
【信息安全原理】——IP及路由安全(学习笔记)
目录 🕒 1. IPv4协议及其安全性分析🕒 2. IPsec(IP Security)🕘 2.1 IPsec安全策略🕤 2.1.1 安全关联(Security Association, SA)🕤 2.1.2 安全策略(Security…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
