题目描述
思路解析动画文字版
把两个数右对齐摆好,从最右边那一列开始往左加,每列算出「本位数字 + 是否进位」。下面就一列一列地演示。
两个数不一样长怎么办?短的那个走完后,缺的位就当成 0 来加。下面这排格子是要填的结果,我们从右往左一格一格填进去。
结果槽 · 还全是空的:这 4 个格子是结果的「位子」(最多 3 位,留 1 个给可能的进位)。下划线 _ 表示还没填。我们从最右边那一格开始。
第 1 列(个位) · 对齐:指针落在最右格(个位)。num1 末位是 6,num2 末位是 7,加上进位 0。先把这一列的三个数找齐。
第 1 列 · 相加:6+7=13,满 10 了!个位数字取 13 除以 10 的余数 3,进位取 13 除以 10 的商 1,留给下一列。
第 1 列 · 填入 3:把 3 填进最右格(变绿)。进位 1 记在心里。两个指针一起往左挪一位,处理十位。
第 2 列(十位) · 对齐:指针移到十位格。num1 这位是 5,num2 这位是 7,别忘了还要加上上一列的进位 1。
第 2 列 · 相加:5+7+1=13,又满 10。本位还是 3(13%10),又产生一个进位 1(13/10)。进位会像接力一样一直传下去。
第 2 列 · 填入 3:十位填 3(再变绿一格)。进位仍是 1。指针继续左移,处理百位。
第 3 列(百位) · num2 没了:百位这里 num2 已经走完了(它只有两位)。这就是短的补 0:num2 这位当成 0 来加。
第 3 列 · 相加:4+0+1=5,这次不满 10,本位就是 5,进位归 0。
第 3 列 · 填入 5:百位填 5。现在两个数都扫完、进位也归 0,加法结束。最左那格没用上(因为没多出进位)。
完成 · 读出结果:我们是从右往左填的,但读的时候从左往右正好就是 533。校验:456 + 77 = 533 ✓。最左空格变灰丢弃。
再演一例 · 11 + 123(不等长):换一对不等长的数 11 + 123 再走一遍,专看「短的那个走完后补 0」。指针先落在个位。
11+123 · 个位:个位:1+3=4,不满 10。填 4,无进位。指针左移。
11+123 · 十位:十位:1+2=3。填 3。此时 num1(只有两位)走完了,但 num2 还有百位。
11+123 · 百位(num1 没了):百位:num1 已越界补 0,num2 是 1,得 1。11+123 = 134 ✓。不管谁短,缺的位补 0 就统一了。
重点是那个 or carry:就算两个数都加完了,只要还剩一个进位(比如 99+1),也必须再多算一列把进位的 1 落下来。下面专门演示这个坑。
坑点实演 · 99 + 1 起步:换 99 + 1 看进位长出新位。结果槽留 3 格(2 位数 + 1 个进位位)。指针落在个位。
坑点实演 · 个位相加:个位:9+1=10,满 10。本位取余数 0,进位取商 1。
坑点实演 · 填入 0:个位填 0(变绿),进位 1 带走。指针左移到十位。
坑点实演 · 十位:十位:num1 是 9,num2 补 0,加进位 1 = 10。又填 0,进位还是 1。此时两个数都走完了——但进位还在!
坑点实演 · 多出一位:因为有 or carry 条件,循环再走一次,把剩下的进位 1 填到最高位。99+1 = 100,正好多出一位。漏了 or carry 就会错成 "00"。
边界三连:先想进位长新位(99+1)、不等长(11+123)、全零(0+0)三种,代码就稳了。
面试追问:把「为何不能转 int」和「or carry 的作用」讲清楚,是这题面试的得分点。
参考代码
class Solution: def addStrings(self, num1, num2): i, j = len(num1) - 1, len(num2) - 1 carry = 0 res = [] while i >= 0 or j >= 0 or carry: x = ord(num1[i]) - ord('0') if i >= 0 else 0 y = ord(num2[j]) - ord('0') if j >= 0 else 0 s = x + y + carry res.append(str(s % 10)) # 本位 carry = s // 10 # 进位 i -= 1 j -= 1 return ''.join(reversed(res))复杂度
- 时间复杂度:O(max(m,n)),m、n 是两串长度;循环次数 = 较长那串的位数(最多再多 1 列给进位),每列常数操作
- 空间复杂度:O(max(m,n)),结果串长度约等于较长串(最多 +1),除结果外只用了 i/j/carry 几个变量
易错点
面试追问把动画讲成自己的话
追问为什么不能直接转成整数相加?
追问两个数不一样长怎么处理?
追问如果要做字符串相乘(LC43)思路类似吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最长回文子串
LeetCode 5 · 中等 · 沿着 字符串套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题