力扣66.加一

【LeetCode题解】数组模拟加法:加一(Plus One)
目录
-
一、题目描述
-
二、题目分析
-
三、解法思路与代码实现
- 方法一:模拟进位(推荐)
- 方法二:大数库(直观但不推荐)
- 方法三:递归解法(扩展思路)
-
四、总结对比
-
五、思考延伸
一、题目描述
给定一个表示 大整数 的整数数组 digits
,其中 digits[i]
是整数的第 i 位数字。数字按从左到右(最高位到最低位)排列,不包含任何前导 0。
请你给这个大整数 加一,并返回结果数组。
示例
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:123 + 1 = 124
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:4321 + 1 = 4322
示例 3:
输入:digits = [9]
输出:[1,0]
解释:9 + 1 = 10
提示
- 1 <= digits.length <= 100
- 0 <= digits[i] <= 9
digits
不包含任何前导 0
二、题目分析
这是一个典型的 数组模拟加法 的问题。
关键点是处理 进位:
-
如果末尾不是 9,直接加一即可。
- 例:
[1,2,3] -> [1,2,4]
- 例:
-
如果末尾是 9,则需要进位,继续向前传播。
- 例:
[9] -> [1,0]
- 例:
[9,9,9] -> [1,0,0,0]
- 例:
因此,从 后往前 处理数组最合适。
三、解法思路与代码实现
方法一:模拟进位(推荐解法)
思路:
从末尾向前遍历,遇到小于 9 的数字就加一并返回;
遇到 9 则变成 0,继续进位;
如果所有数字都是 9,最后需要在最前面补一个 1。
java
class Solution {
public int[] plusOne(int[] digits) {
int n = digits.length;
for (int i = n - 1; i >= 0; i--) {
if (digits[i] < 9) {
digits[i]++;
return digits;
}
digits[i] = 0; // 进位
}
// 全是9的情况,例如 [9,9,9] -> [1,0,0,0]
int[] result = new int[n + 1];
result[0] = 1;
return result;
}
}

复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(1)
这是最优解。
方法二:使用大数库(直观但不推荐)
思路:
把数组转成字符串,再转成大整数,直接加一,最后再转回数组。
java
import java.math.BigInteger;
class Solution {
public int[] plusOne(int[] digits) {
StringBuilder sb = new StringBuilder();
for (int d : digits) {
sb.append(d);
}
BigInteger num = new BigInteger(sb.toString());
num = num.add(BigInteger.ONE);
String str = num.toString();
int[] result = new int[str.length()];
for (int i = 0; i < str.length(); i++) {
result[i] = str.charAt(i) - '0';
}
return result;
}
}

复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(n),需要额外字符串存储。
虽然代码简洁,但不满足"常量额外空间"的要求。
方法三:递归解法(扩展思路)
思路:
递归处理最后一位,如果需要进位则递归处理前一位。
java
class Solution {
public int[] plusOne(int[] digits) {
return helper(digits, digits.length - 1);
}
private int[] helper(int[] digits, int index) {
if (index < 0) {
int[] result = new int[digits.length + 1];
result[0] = 1;
return result;
}
if (digits[index] < 9) {
digits[index]++;
return digits;
}
digits[index] = 0;
return helper(digits, index - 1);
}
}

复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(n),递归栈空间。
优雅但不够高效。
四、总结对比
方法 | 思路 | 时间复杂度 | 空间复杂度 | 是否推荐 |
---|---|---|---|---|
方法一 | 模拟进位 | O(n) | O(1) | 强烈推荐 |
方法二 | 大数库 | O(n) | O(n) | 不推荐 |
方法三 | 递归 | O(n) | O(n) | 可作为思路扩展 |
结论: 在面试或实际场景中,方法一 是最优解,符合题目对时间和空间的要求。
五、思考延伸
-
如果题目改为 加 k,该如何实现?
- 类似处理,逐位进位,直到 k 为 0。
-
如果是 大整数减一 呢?
- 同理,逐位处理借位。