• leetcode 精选top面试题


    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)。

  • 相关阅读:
    Seaborn基础3
    【C语言】将输入的10个整数逆序输出
    【C语言】(数组方式)输出一组成绩中的最高分与最低分
    【C语言】(数组方式)求n名同学的平均成绩
    【C语言】编写程序,输出以下图形
    【C语言】输入一个年份和月份,输出该月的天数
    【C语言】输入圆的半径,求解圆的周长和面积
    Draw.io--自认为最好用的流程图绘制软件
    【C语言】极坐标转换为直角坐标
    【C语言】计算N名同学的某门功课的平均成绩
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/14090851.html
Copyright © 2020-2023  润新知