2. 两数相加

中等 含交互动画

学完这道你应该能: 说清它为什么用「模拟」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

AI 私教 · 就着本题动画讲
卡住了不用硬扛,按 8 步把这题真正走通。
从读题、试解、找法到手写代码,边问边打勾,适合第一次系统学算法的同学。

题目描述

两条链表各表示一个数(每个节点一位、个位在表头),返回它们和的链表。

链表 A = 2 → 4 → 3 (即 342)
链表 B = 5 → 6 → 4 (即 465)
输出 = 7 → 0 → 8 (即 807)

思路解析

两个指针同时走,每位算 a + b + carry:结果对 10 取余是这一位的数字,整除 10 是进位带到下一位。哪条短了就当它是 0。最后如果还有进位,再补一个节点。

起步 · 指针对齐个位:两个指针 p 同时停在两条链的表头(个位)。进位 carry=0,结果链表还空着(虚线占位)。逆序存的好处:表头就是个位,直接从这里开始竖式加。

个位 · 2 + 5 + 0 = 7:个位:a+b+carry = 2+5+0 = 7,没满十。本位 7 = 7%10,进位 carry = 7//10 = 0。tail.next = ListNode(7),结果链表长出第一个节点 7,tail 指向它。

十位 · 指针前移:两个输入指针各往前走一格,来到十位 4 和 6(个位已结算,标灰)。结果链表的 tail 仍停在 7。

十位 · 4 + 6 + 0 = 10 → 满十进一:十位:4+6+0 = 10,满十了!本位写 10%10 = 0,进位 carry = 10//10 = 1 带到下一位。结果链表接上 0,tail 前移。这一步的进位是最容易漏的地方。

百位 · 指针前移(别忘 carry=1):输入指针走到百位 3 和 4。注意手里还攥着上一位的进位 carry=1,这一位相加时要带上它。

百位 · 3 + 4 + 1 = 8:百位:3+4+carry(1) = 8,没满十。本位 8,进位归 0。结果链表长出第三个节点 87 → 0 → 8

两条都走完 · 查最后的进位:两条输入链都走到头,指针变空。最后再看一眼 carry:这里 carry=0,不用补。如果它是 1(比如 5+5=10),还得再给结果链表接一个值为 1 的节点——这正是循环条件要带 carry 的原因。

完成:逐位相加、满十进一,返回的结果链表 7 → 0 → 8,就是 342 + 465 = 807。

链表竖式加法的三件套:逐位 divmod 取「本位/进位」、短的补 0、哨兵起头。循环条件写成 l1 or l2 or carry 是优雅收尾的关键。

参考代码(Python)

Python
1dummy = tail = ListNode()
2carry = 0
3while l1 or l2 or carry:              # 还有位或进位就继续
4    a = l1.val if l1 else 0           # 短的当 0
5    b = l2.val if l2 else 0
6    s = a + b + carry
7    carry, digit = divmod(s, 10)      # 进位, 本位
8    tail.next = ListNode(digit); tail = tail.next
9    l1 = l1.next if l1 else None; l2 = l2.next if l2 else None
10return dummy.next

复杂度分析

  • 时间复杂度:O(max(m,n)) —— 按较长的位数走
  • 空间复杂度:O(max(m,n)) —— 结果链表长度

套路模板

记住骨架:while l1 or l2 or carry、divmod 拆本位与进位、短的补 0、哨兵收尾。大数相加、字符串相加都是这套。

Python
1dummy = tail = ListNode(); carry = 0
2while l1 or l2 or carry:
3    s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry
4    carry, digit = divmod(s, 10)
5    tail.next = ListNode(digit); tail = tail.next
6    l1, l2 = l1 and l1.next, l2 and l2.next
7return dummy.next

易错点

  • 错误写法:循环只写 while l1 and l2正确写法:while l1 or l2 or carry(不等长、或最高位还有进位时会漏算)
  • 错误写法:忘了最后的进位正确写法:carry 也作为循环条件(如 5+5=10,最后要补一个 1 节点)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →160. 相交链表 ← 返回题库