LeetCode 66简单数学 & 几何
加一 图解题解
这道题到底在问什么
给定一个非负整数,它用一个数组表示:每个元素是一个数位,数组开头是最高位。把这个整数加 1,返回结果数组。
- 输入
- digits = [2,9,9,9,9,9]
- 输出
- [3,0,0,0,0,0](299999 + 1 = 300000)
最优解:一步一步想明白
- 3核心只有两种结局:这一位加完没满 10 → 当场收工;满了 10 → 本位归 0、进位继续向左。看下面把 299999 加 1 一位位走完。
- 4开始之前:整个数是 299999,我们手里攥着一个要加进去的 1(记成 carry = 1)。指针从最右边出发。
- 5指针走到下标 5,这一位现在是 9。手里还有 carry = 1 要加进来。
- 6这一位加上进位:9 + 1 = 10。满了 10,这位要归 0、进位继续往左带。
- 7下标 5 写成 0(标红的就是它),进位 carry 还是 1,接着去处理它左边那一位。
- 8指针走到下标 4,这一位现在是 9。手里还有 carry = 1 要加进来。
- 9这一位加上进位:9 + 1 = 10。满了 10,这位要归 0、进位继续往左带。
- 10下标 4 写成 0(标红的就是它),进位 carry 还是 1,接着去处理它左边那一位。
- 11指针走到下标 3,这一位现在是 9。手里还有 carry = 1 要加进来。
- 12这一位加上进位:9 + 1 = 10。满了 10,这位要归 0、进位继续往左带。
- 13下标 3 写成 0(标红的就是它),进位 carry 还是 1,接着去处理它左边那一位。
- 14指针走到下标 2,这一位现在是 9。手里还有 carry = 1 要加进来。
- 15这一位加上进位:9 + 1 = 10。满了 10,这位要归 0、进位继续往左带。
- 16下标 2 写成 0(标红的就是它),进位 carry 还是 1,接着去处理它左边那一位。
- 17指针走到下标 1,这一位现在是 9。手里还有 carry = 1 要加进来。
- 18这一位加上进位:9 + 1 = 10。满了 10,这位要归 0、进位继续往左带。
- 19下标 1 写成 0(标红的就是它),进位 carry 还是 1,接着去处理它左边那一位。
- 20指针走到下标 0,这一位现在是 2。手里还有 carry = 1 要加进来。
- 21这一位加上进位:2 + 1 = 3。没满 10,写下它就彻底结束了。
- 22下标 0 写成 3(绿色高亮),进位用完了 carry = 0。左边的位一个都不用碰,可以收工。
- 23一路走完,进位被消化干净,最终结果是 [3,0,0,0,0,0],也就是 299999 + 1 = 300000。
⚠️ 容易写错的地方
✗ 错:忘了处理「一路全是 9」的情况(如 [9,9])
✓ 对:循环结束后还没返回,就在最前面补一个 1
[9,9]+1=[1,0,0],长度会变长,漏了这步会返回错误的 [0,0]
✗ 错:从左往右(最高位)开始加
✓ 对:必须从最右边的最低位开始
进位是向高位(左)传的,从低位起才能顺着进位方向处理
✗ 错:用整数相加再拆位
✓ 对:直接在数组上逐位进位
数组可能很长,转成整数会溢出;逐位处理才稳妥
完整代码(Python / C++ / Java)
Python
def plusOne(digits):
i = len(digits) - 1 # 从最低位(最右)开始
while i >= 0:
if digits[i] < 9: # 不满 9:加 1 就收工
digits[i] += 1
return digits
digits[i] = 0 # 是 9:本位归 0,进位继续
i -= 1
return [1] + digits # 一路 9:最高位再补个 1C++
vector<int> plusOne(vector<int>& d){
for (int i = d.size()-1; i >= 0; i--) {
if (d[i] < 9) { d[i]++; return d; }
d[i] = 0;
}
d.insert(d.begin(), 1);
return d;
}Java
public int[] plusOne(int[] d) {
for (int i = d.length-1; i >= 0; i--) {
if (d[i] < 9) { d[i]++; return d; }
d[i] = 0;
}
int[] r = new int[d.length+1];
r[0] = 1;
return r;
}复杂度
时间
O(n)
最坏情况(全是 9)要从最右一直进位到最左,每位看一次
空间
O(1)
原地在数组上改;只有全 9 时才新建一个长度加一的数组
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 加一 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
为什么要从数组最右边开始处理?+
最右边是最低位(个位)。加法的进位是从低位向高位传的,所以要从最低位(最右)起,顺着进位方向往左走。
什么情况下结果数组会比原来长?+
只有当原数组全是 9 时(如 [9,9])。所有位都进位归零后,最高位还有一个进位,需要在最前面新增一位 1。
能不能把数组转成整数加 1 再转回去?+
小数组可以,但题目里数组可能很长,转成整数会超出 int/long 的范围导致溢出。逐位进位是更稳的通用做法。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄把 加一 一步步讲透(全站已上线 905 份讲透,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
把这道题真正拿下
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。