news 2026/2/9 23:11:32

从零开始学算法——链表篇3:合并两个有序链表 + 两数相加

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零开始学算法——链表篇3:合并两个有序链表 + 两数相加

在链表类算法题中,我们经常听到“虚拟头节点”或“哑节点”(Dummy Node)这个概念。很多初学者往往是照猫画虎,看别人用了也就跟着用。

其实可以 简单总结为“只有需要对头节点的前一个节点进行操作的时候,才需要用 dummy。”

这句话非常精准地概括了 Dummy Node 在链表修改(如删除倒数第 N 个节点、反转链表)中的作用。但在链表构建(如合并链表、两数相加)类题目中,Dummy Node 扮演了另一个至关重要的角色:消除“冷启动”差异,统一边界逻辑

今天我们就通过“合并两个有序链表”和“两数相加”这两道经典题目,来深度解析 Dummy Node 如何让代码化繁为简。


一、 合并两个有序链表:拉链法的极致简化

题目:将两个升序链表合并为一个新的升序链表并返回。

1. 痛点分析:如果没有 Dummy Node

如果我们在不使用 Dummy Node 的情况下构建一个新链表,代码逻辑通常是这样的:

  1. 比较list1list2的头节点,确定谁小。

  2. 将结果链表的head指向那个较小的节点。

  3. 之后的循环中,我们操作的是cur->next

你会发现,**“确定第一个节点”“确定后续节点”**的逻辑是不一样的。我们需要额外的if-else来处理头节点的初始化。这就是所谓的“冷启动”问题。

2. 优化思路:虚拟头节点的“锚点”作用

使用ListNode dummy(0);在栈上创建一个虚拟节点,它的作用就像一个锚点

  • cur指针最初指向dummy

  • 此后,无论是添加第一个有效节点,还是添加第一百个节点,我们统一的操作都是cur->next = node

这种写法将头节点的处理逻辑降维成了普通节点的处理逻辑。

3. 代码深度解析

C++代码实现:

class Solution { public: ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) { // 在栈上创建 dummy,自动管理内存,无需手动 delete ListNode dummy(0); ListNode* cur = &dummy; ListNode* cur1 = list1; ListNode* cur2 = list2; // 核心逻辑:谁小移谁,像拉拉链一样咬合 while (cur1 && cur2) { if (cur1->val < cur2->val) { cur->next = cur1; cur1 = cur1->next; } else { cur->next = cur2; cur2 = cur2->next; } // 别忘了移动结果链表的指针 cur = cur->next; } // 优化点:链表天然的优势 // 当一个链表遍历完,另一个链表剩余部分直接接在后面即可,无需遍历 cur->next = cur1 ? cur1 : cur2; return dummy.next; } };

4. 时空复杂度分析

  • 时间复杂度:O(M + N)。其中 M 和 N 是两个链表的长度。我们最多只遍历了两个链表一次。

  • 空间复杂度:O(1)。这是一次原地合并。我们并没有创建新的节点(除了 dummy),只是调整了原有节点的next指针,将它们重新串联起来。


二、 两数相加:模拟加法与进位的艺术

题目:两个非空链表代表两个非负整数,数字逆序存储,请将它们相加并以链表形式返回。

1. 难点分析

这就好比我们在纸上算加法:

  1. 对齐:链表逆序存储(个位在头),刚好符合我们从低位算起的习惯。

  2. 长度不等:一个数是 3 位,一个数是 5 位,短的那个数高位要视为 0。

  3. 进位(Carry):9 + 1 = 10,需要向后进 1。最容易忽略的是最后一位相加如果还有进位,需要补一个新的节点

2. 代码深度解析

这段代码的精髓在于while循环的条件控制。

C++代码实现:

class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode dummy(0); ListNode* cur = &dummy; int carry = 0; // 进位记录 // 这里的条件非常优雅:只要 l1 没走完,或者 l2 没走完,或者还有进位没处理 // 循环就继续。这完美解决了“长度不等”和“最后进位”的问题。 while (l1 || l2 || carry) { int sum = carry; // 当前位的和,先加上进位 if (l1) { sum += l1->val; l1 = l1->next; } if (l2) { sum += l2->val; l2 = l2->next; } // 创建新节点存储当前位的值(个位) cur->next = new ListNode(sum % 10); cur = cur->next; // 更新进位(十位) carry = sum / 10; } return dummy.next; } };

3. 时空复杂度分析

  • 时间复杂度:O(max(M, N))。我们需要遍历较长的那个链表,如果最后有进位,则多走一步。

  • 空间复杂度:O(max(M, N))。注意,这里和上一题不同。上一题是重组旧节点,这一题是创建新节点。我们需要创建一个新的链表来存储结果,其长度最长为max(M, N) + 1

说明:

两者时间复杂度为什么一个是O(M + N),一个是O(max(M, N))

核心区别:是一个一个走还是一对一对走

比如第一题我们一次循环迭代指针只做了一次移动,而第二题是一起移动的,这就是区别。


三、 总结:Dummy Node 的双重境界

我们可以把 Dummy Node 的作用总结为两层境界:

  1. 防御层(操作前驱): 当你需要删除或插入位置i的节点时,你需要找到位置i-1。如果i=0(头节点),i-1不存在。此时 Dummy Node 充当了那个永远存在的pre节点,统一了操作逻辑

  2. 构建层(统一构建): 也就是本文讨论的场景。当你需要从无到有构建一条新链表时,结果链表的头节点在循环开始前往往是未知的(或者需要复杂的判断逻辑来生成)。此时 Dummy Node 作为一个静态的占位符,让我们可以无脑执行cur->next = new_node统一了初始化逻辑

这就是链表中“虚拟头节点”的本质。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 16:45:24

如何快速掌握ISO20000标准:信息技术服务管理体系终极指南

如何快速掌握ISO20000标准&#xff1a;信息技术服务管理体系终极指南 【免费下载链接】ISO20000信息技术服务管理体系标准新版标准解读PDF下载 探索信息技术服务管理的最新标准&#xff0c;本仓库精心整理了《ISO20000新版标准解读》PDF&#xff0c;深入剖析标准条款&#xff0…

作者头像 李华
网站建设 2026/2/4 16:29:31

企业级 AI 智能体规模化落地:MCP+GraphRAG+Agent

文章解析了企业级AI Agent落地的四大核心趋势&#xff1a;MCP构建统一连接层、GraphRAG实现精准知识响应、AgentDevOps保障系统可靠性、RaaS让价值可衡量。介绍了AI Agent在营销运营、招聘HR等场景的应用实践&#xff0c;以及企业落地自检清单。指出当前AI Agent正从"工具…

作者头像 李华
网站建设 2026/2/8 0:14:34

基于web的二手书交易平台设计与实现开题报告

班级&#xff1a;网络工程2101班学号&#xff1a;202325360111姓名&#xff1a;指导教师&#xff1a;刘诗瑾本科学生毕业论文&#xff08;设计&#xff09;开题报告毕业论文&#xff08;设计&#xff09;题目&#xff1a;基于web的二手书交易平台设计与实现开题报告内容:1 毕业…

作者头像 李华
网站建设 2026/2/9 10:02:02

苹果生态AI新纪元:本地化大模型如何重塑您的智能体验

苹果生态AI新纪元&#xff1a;本地化大模型如何重塑您的智能体验 【免费下载链接】Qwen3-32B-MLX-6bit 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-32B-MLX-6bit 您是否曾遇到过这样的情况&#xff1a;在处理敏感文档时&#xff0c;因担心隐私泄露而不得…

作者头像 李华
网站建设 2026/2/9 2:02:47

终极SimSun字体获取指南:如何快速使用经典中文字体

SimSun.ttf字体是一款备受推崇的中文排版字体&#xff0c;以其清晰优雅的设计风格而闻名。这款经典中文字体在文档编辑和设计领域中发挥着重要作用&#xff0c;为用户提供专业的中文显示效果。 【免费下载链接】simsun.ttf字体文件下载仓库 SimSun.ttf是一款经典的中文字体&…

作者头像 李华
网站建设 2026/2/5 22:15:49

探索Android代码编辑器的革新之路:Sora-Editor深度解析

探索Android代码编辑器的革新之路&#xff1a;Sora-Editor深度解析 【免费下载链接】sora-editor A multifunctional Android code editor library. (aka CodeEditor) 项目地址: https://gitcode.com/gh_mirrors/so/sora-editor 在移动开发日益复杂的今天&#xff0c;一…

作者头像 李华