题目描述
思路解析动画文字版
下面 16 步动画会按主解代码推进,而不是泛泛讲题型。
1. 看输入:l1=7243、l2=564,链表最高位在最前面。加法要从个位算起,而个位在链表末尾,所以先想办法反向取数。
2. l1 压栈 s1:顺序遍历 l1 全部入栈:s1=[7,2,4,3],栈顶是最后压入的 3,正好是 l1 的个位。top 指向栈顶 3。
3. l2 压栈 s2:同样把 l2 全部入栈:s2=[5,6,4],栈顶是 4,也就是 l2 的个位。现在两个栈顶都对齐到了个位。
4. 初始化:进位 carry=0,结果链 head=None。接下来每轮各弹一个栈顶相加,新数位用头插法接到 head 前面。
5. 第1轮·弹栈顶:两栈各弹一个栈顶:s1 弹出 3、s2 弹出 4(划掉表示已出栈)。这就是两数的个位。
6. 第1轮·相加:total = carry + 3 + 4 = 0 + 3 + 4 = 7。本位数字 = 7 除 10 的余数 = 7,进位 = 7 除 10 的商 = 0。
7. 第1轮·头插:新建数字 7 头插到结果最前面:head=7。carry 更新为 0。s1 剩 [7,2]、s2 剩 [5],进入下一轮。
8. 第2轮·弹栈顶:继续弹栈顶:s1 弹出 4、s2 弹出 6(十位)。栈顶总是当前要处理的那一位,无需操心对齐。
9. 第2轮·相加:total = carry + 4 + 6 = 0 + 4 + 6 = 10。本位数字 = 10 除 10 的余数 = 0,进位 = 10 除 10 的商 = 1。
10. 第2轮·头插:数字 0 头插到最前:结果变成 0→7。carry=1 被记下,会带进下一轮。s2 已空,s1 还剩 [7]。
11. 第3轮·弹栈顶:s1 弹出 2;s2 已空,这一位只取 0。注意 carry=1 也要参与,所以本轮三项是 1、2、0。
12. 第3轮·相加:total = carry + 2 + 0 = 1 + 2 + 0 = 8。本位数字 = 8 除 10 的余数 = 8,进位 = 8 除 10 的商 = 0。
13. 第3轮·头插:数字 8 头插到最前:结果变成 8→0→7。carry 归 0。s1 还剩栈顶 7,循环条件仍成立,再走一轮。
14. 第4轮·弹+加:弹出 s1 最后的 7,s2 空补 0:total = carry + 7 + 0 = 0 + 7 + 0 = 7。本位数字 7,进位 0。
15. 第4轮·头插:数字 7 头插到最前:结果变成 7→8→0→7。两栈都空、carry=0,循环条件 s1 或 s2 或 carry 全部不成立。
16. 返回结果:返回 head=[7,8,0,7],正是 7243 + 564 = 7807 的高位在前链表。头插法天然让最后算出的高位排在最前面。
记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
参考代码
class Solution: def addTwoNumbers(self, l1, l2): s1 = [] s2 = [] while l1: s1.append(l1.val) l1 = l1.next while l2: s2.append(l2.val) l2 = l2.next carry = 0 head = None while s1 or s2 or carry: total = carry if s1: total += s1.pop() if s2: total += s2.pop() node = ListNode(total % 10) node.next = head head = node carry = total // 10 return head复杂度
- 时间复杂度:O(m+n),遍历两条链表
- 空间复杂度:O(m+n),两个栈和结果链
易错点
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
K 个一组翻转链表
LeetCode 25 · 困难 · 沿着 链表套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题