66. 加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
示例 3:
输入:digits = [0]
输出:[1]
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
思路一:大数加法
从后往前遍历数组进行大数加法,这里没有第二个加数,只有初值为1的进位,每个数位的结果保存在字符串中。最终把结果字符串转存到数组中。
1 class Solution {
2 public int[] plusOne(int[] digits) {
3 // 大数加法,只不过这里只需要加一,需要考虑进位
4 int fn = 1, temp = 0;
5 int len = digits.length;
6 StringBuilder sb = new StringBuilder();
7 //
8 for(int i = len - 1; i >= 0; --i){
9 temp = digits[i] + fn;
10 sb.append(temp % 10);
11 fn = temp / 10;
12 }
13 // 最后还需要考虑最后的进位
14 if(fn > 0){
15 sb.append(fn);
16 }
17
18 // 把结果字符串再拷贝到数组中,注意字符串是逆序的
19 len = sb.length();
20 int[] res = new int[len];
21 for(int i = 0; i < len; i++){
22 res[i] = sb.charAt(len - i - 1) - '0';
23 }
24 return res;
25 }
26 }
leetcode 执行用时:1 ms, 在所有 Java 提交中击败了5.12%的用户, 内存消耗:36.7 MB, 在所有 Java 提交中击败了90.60%的用户
复杂度分析
时间复杂度:O(n)。遍历了一个原数组,求加一后的结果,又遍历了一次结果字符串,把最终结果转存到数组中,所以时间复杂度为O(n)。
空间复杂度:O(n)。如果不考虑结果数组的话,空间开销是字符串的大小,为O(n)。
思路二:
思路参考:https://leetcode-cn.com/problems/plus-one/solution/java-shu-xue-jie-ti-by-yhhzw/
由于这题的第二个加数为1, 所以可以直接在原数组在进行大数加法,
如果最后没有产生进位,直接返回原属组;
如果最中产生了进位,一定是99+1 = 100, 或者是99..99 + 1 = 100..000的情况,如果最后还有进位,直接新建一个数组,把第一个置为1即可。
1 class Solution {
2 public int[] plusOne(int[] digits) {
3 // 大数加法,只不过这里只需要加一,需要考虑进位
4 int fn = 1, temp = 0;
5 int len = digits.length;
6 for(int i = len - 1; i >= 0; --i){
7 temp = digits[i] + fn;
8 digits[i] = temp % 10;
9 fn = temp / 10;
10 }
11 // 最后还需要考虑最后的进位
12 if(fn == 0){
13 return digits;
14 }
15 int[] res = new int[len + 1];
16 res[0] = 1;
17 return res;
18 }
19 }
复杂度分析:
时间复杂度:O(n)。遍历了一次数组,所以时间复杂度为O(n)。
空间复杂度:O(1)。因为没有借助StringBuilder。
思路三:
思路二的优化,在进行大数加法的循环内部,如果进位已经为0了,没必要继续往下加了,可以直接返回。
循环结束后需要处理存在进位的情况。
1 class Solution {
2 public int[] plusOne(int[] digits) {
3 // 大数加法,只不过这里只需要加一,需要考虑进位
4 int fn = 1, temp = 0;
5 int len = digits.length;
6 for(int i = len - 1; i >= 0; --i){
7 temp = digits[i] + fn;
8 digits[i] = temp % 10;
9 fn = temp / 10;
10 if(fn == 0){
11 return digits; // 如果进位已经为0了,没必要继续往下加了
12 }
13 }
14 // 程序能走到这里,肯定因为最后存在进位,所以没有在循环内部返回,所以处理他
15 int[] res = new int[len + 1];
16 res[0] = 1;
17 return res;
18 }
19 }
leetcode 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户, 内存消耗:37 MB, 在所有 Java 提交中击败了62.69%的用户
复杂度分析:
时间复杂度:O(n)。遍历了一次数组,所以时间复杂度为O(n)。总体时间复杂度没有变,但是效率其实是有所提升的。
空间复杂度:O(1)。