图解题库 / 链表 · 模拟

2. 两数相加

中等 含交互动画

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

题目描述

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

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

思路解析

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

个位 · 2 + 5 = 7:个位:2 + 5 + 进位0 = 7,没满十。写下 7,进位 carry=0。结果:7。两指针往前走。

十位 · 4 + 6 = 10 → 进位:十位:4 + 6 + 0 = 10,满十!这一位写 10%10 = 0,进位 carry = 10//10 = 1 带到下一位。结果:7 → 0

百位 · 3 + 4 + 1 = 8:百位:3 + 4 + 进位1 = 8,没满十。写下 8,carry=0。结果:7 → 0 → 8

两条都走完 · 无进位 → 结束:两条链都走完,最后 carry=0,不用补节点。最终结果 7 → 0 → 8,就是 807。(如果最后 carry=1,还得再接一个值为 1 的节点)

链表竖式加法的三件套:逐位 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. 相交链表 ← 返回题库