题目描述
两条链表各表示一个数(每个节点一位、个位在表头),返回它们和的链表。
链表 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 节点)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。