leetcode 精选top面试题 - 66. 加一

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 }
leetcode :执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户,内存消耗:36.9 MB, 在所有 Java 提交中击败了76.04%的用户

复杂度分析:

时间复杂度: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)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值