一个初学者用 C++ 解答合并 K 个升序序列的心路历程
写在前面大家好我最近刚刚开始接触 C也是刚刚开始接触算法。这几天在学习 C 链表时我的心情可以说是像过山车一样。以前习惯了 C 语言里苦哈哈地用malloc分配内存、小心翼翼地处理NULL指针的我在接触到 C 的构造函数和虚拟头节点后虽然说刚开始接受起来还是有点困难但好在最终还是克服了。趁着热乎劲我在 LeetCode 上用 C 轻松搞定了第 21 题合并两个有序链表。我自信满满地点击了下一题实不相瞒这道合并 K 个升序序列题目的 Hard 标签确实吓到我了我还不觉得自己有独立解决困难题目的能力。但经过一番挣扎我发现只要转变思维借用 C 的优势初学者也完全可以对 Hard 题进行降维打击今天我就从一个初学者的视角一步步撕开这道题的外衣并尽可能详细地把优先队列这一知识点解释通透。1. 题目初探题目描述很简单给你一个链表数组每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中返回合并后的链表。下面是 Leetcode 官方的示例输入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对于这道题大家可以带入一下生活桌子上有 K 叠已经从小到大理好的扑克牌。现在你的任务是把它们合并成一叠全新且有序的扑克牌你会怎么做2. 破局思路一开始我完全没有思路但我突然想到我刚刚不是才写过合并 2 个链表的代码吗这两道题颇有相似之处。只能合并两叠牌的代码我已经写过了那合并 K 叠牌的暴力解法不就有了吗我先把第 1 叠和第 2 叠放进机器融合成一大叠。我拿着这新的一大叠再和第 3 叠放进机器……一直循环 K-1 次成功。我直接复用第 21 题的代码把它封装成一个mergeTwoLists函数然后用一个for循环搞定。提交代码之后也是成功通过了但就是耗时长的吓人有 100 多毫秒。但冷静下来一算时间复杂度越到后面合并后的链表就越长每次都要从头遍历全部的节点如果在真实的项目中早就卡死了。在看了评论区的大神的解法之后我才意识到C 远没有我想象的这么简单真正的大杀器才刚刚登场。3. 优先队列的降维打击有没有一种方法不需要我们辛辛苦苦地两条链表互相比较有的C 的 STL 标准模板库中有一个和这道题简直是天生一对的工具——优先队列。3.1 什么是优先队列从它的名字我们就能看出来它不是普通的队列当然这好像是一句废话。普通队列就是将就一个先来后到。而优先队列就像是医院的急诊室谁的病重谁先进去。不管你扔进去多少个数据只要你调用出队指令它总是自动把最极端的那个数据最大或最小弹出来。3.2 新的解题思路有了这个工具我们的合并逻辑变得极其方便把 K 叠牌的最上面那一张也就是 K 个链表的头节点全部放进优先队列里面。让优先队列弹出最上面的那一个头节点根据题目我们要让最上面的头节点的val最小。然后看看刚刚拿走的那张牌属于哪一叠从那一叠里再摸下一张牌放进优先队列里补充。一直重复拿牌和补充直到优先队列空了所有链表就完美合并了。因为盒子里最多只有 K 个节点利用优先队列内部的二叉树结构每次放进去或拿出来的时间复杂度只有O(log⁡K)。总时间复杂度瞬间降维到O(Nlog⁡K)运行速度相当的快。4. 优先队列详解思路现在已经很完美了但是这里还有些坑。在 C 中引入#include queue后如果只存整数写priority_queueint pq就行了。但现在我们要存的是链表节点指针ListNode*如果依旧按照常规的方法来写他就会去比较内存地址的大小这不是乱套了吗这就引出了 C 优先队列的完整体模板结构包含三个参数priority_queue 数据类型, 底层容器类型, 比较规则 在 C 中我们通常用仿函数来定义比较规则。这看起来有点吓人但其实就是个重写了()的结构体//比较规则structcmp{booloperator()(ListNode*a,ListNode*b){//优先队列默认是大顶堆。//我们要从小到大排也就是小顶堆所以要反着来用大于号//如果 a 的值大于 b就把 a 沉到下面去。returna-valb-val;}};当优先队列需要比较两个元素时调用cmp()(a, b)。如果返回truea 的优先级低于ba 会被放在堆的下面。如果返回falsea 的优先级高于ba 会被放在堆的上面。我们来梳理一下它的工作原理最后返回的是a-val b-val也就是说当a的val比b的val小时返回false这时a的优先级高于ba会被放在堆的上面正是我们要的结果。定义好规则后我们的优先队列就彻底成型了priority_queueListNode*,vectorListNode*,cmppq;5. 完整代码classSolution{public:structcmp{booloperator()(ListNode*a,ListNode*b){returna-valb-val;//小顶端}};ListNode*mergeKLists(vectorListNode*lists){priority_queueListNode*,vectorListNode*,cmppq;ListNode*dummynewListNode(0);ListNode*currdummy;for(inti0;ilists.size();i){if(lists[i]!nullptr)//必须判断是否为空如果为空还放到优先队列会导致后面minNode-next非法解引用{pq.push(lists[i]);//将所有链表头节点塞入优先队列}}while(!pq.empty())//优先队列不空{ListNode*minNodepq.top();//把最小的拿出来用于后面找它所在的那一叠的下一个节点pq.pop();//弹出最小的curr-nextminNode;//将最小的节点接到我们的新链表上currcurr-next;//让curr指针向后移动一位if(minNode-next!nullptr)//找到刚才弹出的最小节点所在的链表只要下一个节点不为空就塞到优先队列{pq.push(minNode-next);}}ListNode*resultdummy-next;deletedummy;returnresult;}};写在最后回首这几天从 C 语言向 C 跃迁的历程我有了些深刻的感悟关乎我们面对生活和挑战的真实态度。如果你也是一个刚刚踏上编程之路或者正在被某个 Hard 标签的题目按在地上摩擦的初学者我想对你说不要慌张也不要畏惧。底层的功夫慢慢的扎高级的工具勇敢去学。只要逻辑的指针不断向前curr ! nullptr即使再长的链表我们也终将抵达理想的彼岸。本文结束。

相关新闻

KadNap 恶意软件侵袭:华硕路由器构建抗打击僵尸网络

KadNap 恶意软件侵袭:华硕路由器构建抗打击僵尸网络

14000 台华硕设备沦陷,僵尸网络规模持续扩张研究人员发现一个由 14000 台路由器和其他网络设备组成的抗打击僵尸网络,这些设备主要由华硕生产,并被纳入一个用于匿名传输网络犯罪流量的代理网络。自去年 8 月黑莲花实验室发现该僵尸网络以来&a…

2026/7/3 3:40:34 阅读更多 →
STM32开发板

STM32开发板

STM32绝对是学习嵌入式不可绕过的必学单片机了。其片上资源与外设十分适合初学者学习与使用。我是参照江协科技的视频学习的(真的很详细)。教学视频里用于演示的是STM32最小系统板,刚好身边有块STM32和元器件,所以想着自己能够设计…

2026/5/17 12:54:58 阅读更多 →
甲骨文 MySQL 社区版更新:控制权纷争下的新路线图

甲骨文 MySQL 社区版更新:控制权纷争下的新路线图

甲骨文拒绝控制权移交,承诺社区版开发更透明在收到数据库公司联盟及 MySQL 用户要求重组 MySQL 社区版控制权的请求后,甲骨文正式拒绝。该联盟主要成员 Percona 和 VillageSQL 与甲骨文会面,讨论 2 月在线信件提出的更改要求,信件…

2026/5/17 12:54:57 阅读更多 →

最新新闻

E-Hentai Downloader:重新定义漫画资源管理的智能解决方案

E-Hentai Downloader:重新定义漫画资源管理的智能解决方案

E-Hentai Downloader:重新定义漫画资源管理的智能解决方案 在数字内容管理领域,高效获取和整理漫画资源一直是个技术挑战。传统的手动下载方式不仅耗时耗力,还面临着文件管理混乱、资源完整性难以保证等问题。E-Hentai Downloader作为一款基于…

2026/7/4 20:45:44 阅读更多 →
WorkFlow入门Step.1—My Frist WorkFlow Trip!

WorkFlow入门Step.1—My Frist WorkFlow Trip!

自从上次书写的关于《AgileEAS.NET平台开发Step By Step系列-药店系统-索引》使用AgileEAS.NET 敏捷软件开发平台之后,封笔了一段时间,一是最近比较忙,给客户指导培训,通过近20多天的时间,也是开发了一个建议的ERP系统…

2026/7/4 20:43:44 阅读更多 →
Microsoft NLayerApp案例理论与实践 - 基础结构层(Cross-Cutting部分)

Microsoft NLayerApp案例理论与实践 - 基础结构层(Cross-Cutting部分)

NLayerApp中IoC容器的实现 在应用程序设计的过程中,我们会基于这样一个设计准则,就是类型之间的关联应该依赖于接口或者抽象,而非具体的实现。这样就使得我们能够在保证整个程序结构不变的情况下,很方便地替换组件的具体实现方式…

2026/7/4 20:43:44 阅读更多 →
E-Hentai漫画批量下载:3步解锁你的个人数字图书馆

E-Hentai漫画批量下载:3步解锁你的个人数字图书馆

E-Hentai漫画批量下载:3步解锁你的个人数字图书馆 你是否曾在深夜浏览E-Hentai时,发现心仪的漫画集却苦于无法一次性保存?或者因为网络不稳定而不得不反复刷新页面,只为下载那几张珍贵的图片?今天,让我带你…

2026/7/4 20:43:44 阅读更多 →
DWT硬件延时

DWT硬件延时

1、Cortex-M4内核架构2、硬件延时利用计数功能的硬件进行延时,比如单片机片上定时器(Timer),内核滴答定时器(systick)等:__weak void HAL_IncTick(void) {uwTick; } __weak uint32_t HAL_GetTick(void) {return uwTick…

2026/7/4 20:41:43 阅读更多 →
如何通过5个简单步骤实施HARA

如何通过5个简单步骤实施HARA

确保汽车系统的安全性并非易事。随着现代车辆日益复杂,识别并减轻潜在危险变得比以往任何时候都更加关键。这正是危害分析与风险评估(HARA)发挥作用的地方。 HARA是一种结构化方法,旨在评估风险并制定符合ISO 26262(汽…

2026/7/4 20:41:43 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻