LeetCode 445中等链表
两数相加 II 图解题解
这道题到底在问什么
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外,这两个数字都不会以零开头。
- l1,l2
- [7,2,4,3],[5,6,4]
- 输出
- [7,8,0,7]
先想最直接的笨办法
链表指针跟着代码走:推进语句是:s1.append(l1.val)。处理过的部分不再重新枚举。(动画第 10 步)
最优解:一步一步想明白
- 3下面 9 步动画会按主解代码推进,而不是泛泛讲题型。
- 4先读清 两数相加 II 的输入输出链表指针跟着代码走:先把示例输入映射到代码参数:def addTwoNumbers(self, l1, l2):。
- 5s1 = [];s2 = []链表指针跟着代码走:开局只立住必要变量:s1 = [];s2 = []。
- 6while l1:链表指针跟着代码走:主流程从这里开始:while l1:。
- 7if s1:链表指针跟着代码走:题目条件落到这一行:if s1:。
- 8total += s1.pop()链表指针跟着代码走:对应代码:total += s1.pop()。这一行决定当前轮对答案有什么贡献。
- 9用栈反向处理低位链表指针跟着代码走:边界跟着代码看:total += s2.pop()。
- 10s1.append(l1.val)链表指针跟着代码走:推进语句是:s1.append(l1.val)。处理过的部分不再重新枚举。
- 11return head链表指针跟着代码走:到这里,carry 已经能表达题目要求。
- 12return:return head链表指针跟着代码走:最后检查返回形态:返回值、原地修改或设计类状态,要和 LeetCode 判题方式一致。
- 15记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
⚠️ 容易写错的地方
✗ 错:直接从头加
✓ 对:用栈反向处理低位
个位在链表尾部
✗ 错:最后进位丢失
✓ 对:carry 也参与循环条件
999+1 会多出一位
完整代码(Python)
Python
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)
两个栈和结果链
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 两数相加 II 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
这道题为什么用「链表」,换最直接的暴力解会差在哪?+
链表抓住了本题的结构特征,把暴力解里重复的工作省掉;暴力解通常要多嵌套一层枚举,数据一大就超时。具体对比见上文「暴力解及其卡点」与「最优解逐步推演」两节。
时间复杂度为什么是 undefined?怎么推出来的?+
按上文复杂度小节的推导,时间复杂度为 undefined。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。