加一(非空数组)(力扣)

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 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

读题杀了我好多脑细胞。。。

官方给的思路,简直跟我想的一模一样:

当我们对数组 digitsdigits 加一时,我们只需要关注 digitsdigits 的末尾出现了多少个 99 即可。我们可以考虑如下的三种情况:

  • 如果 digitsdigits 的末尾没有 99,例如 [1,2,3][1,2,3],那么我们直接将末尾的数加一,得到 [1,2,4][1,2,4] 并返回;

  • 如果 digitsdigits 的末尾有若干个 99,例如 [1,2,3,9,9][1,2,3,9,9],那么我们只需要找出从末尾开始的第一个不为 99 的元素,即 33,将该元素加一,得到 [1,2,4,9,9][1,2,4,9,9]。随后将末尾的 99全部置零,得到 [1,2,4,0,0][1,2,4,0,0] 并返回。

  • 如果 digitsdigits 的所有元素都是 99,例如 [9,9,9,9,9][9,9,9,9,9],那么答案为 [1,0,0,0,0,0][1,0,0,0,0,0]。我们只需要构造一个长度比 digitsdigits 多 11 的新数组,将首元素置为 11,其余元素置为 00 即可。

对,于是我写出了:

/** * Note: The returned array must be malloced, assume caller calls free(). */
 int* plusOne(int* digits, int digitsSize, int* returnSize){ 
int j;
 if(digits[digitsSize-1]!=9){
 digits[digitsSize-1]++;
 *returnSize=digitsSize; 
return digits;
}
 else{
for(int i=digitsSize-1;i>=0;i--){
if(digits[i]!=9){ 
digits[i]++; 
if(j>i){
 digits[j]=0;
} 
*returnSize=digitsSize;
 return digits;
} 
else{
 int* temp=(int*)malloc(sizeof(int)*(digitsSize+1)); 
for(int i=1;i<digitsSize+1;i++){
 temp[i]=0; 
temp[0]=1; 
*returnSize=digitsSize+1; 
return temp;
} 
}
}
}

和官方的思路完美契合,遗憾的是不能运行。。。

看一个妙人的代码,处处巧合,结果却没错:

int* plusOne(int* digits, int digitsSize, int* returnSize) { 
 int jw = 1;
 int i;
 for (i = digitsSize - 1; i >= 0; i--) {
 digits[i] = digits[i] + jw;
 jw = digits[i] / 10;
 digits[i] = digits[i] % 10;
 } 
*returnSize = digitsSize + jw;
 int* sum = (int*)malloc(sizeof(int) * *returnSize);
 memset(sum, 0, sizeof(int) * *returnSize);
 for (i = digitsSize - 1; i >= 0; i--) { 
 sum[i + jw] = digits[i];
 } 
sum[0] += jw; 
return sum; 
}

这个代码除了不是我写的,真的太完美了。🥹

看题,突破点在于数字是不是9,最后一位开始往前遍历,如果遇到9,就将此位换为0,继续往前遍历,遇到的第一个非9的数字,加一即可返回。如果数组的所有元素都是9,遇不到非9数字,就直接开辟一个新数组,第一位放1,后面直接放0返回新数组。

所以这个题不同输入可能会有不同的返回途径。

/** * Note: The returned array must be malloced, assume caller calls free(). */
 int* plusOne(int* digits, int digitsSize, int* returnSize){ 
for (int i = digitsSize - 1; i >= 0; i--) {
 if (digits[i] != 9) {
 //遇到非9,即可返回
 digits[i] ++; 
*returnSize = digitsSize;
 return digits; 
//直接返回
 } 
else digits[i] = 0;
 //如果当前元素为9,那么加1之后会变0 
} 
*returnSize = digitsSize+1; 
//没遇到非9,元素都是9,另一条路径返回 
int *temp = (int *)malloc(sizeof(int) * (digitsSize+1));
 for(int i = 1; i < digitsSize + 1; i++){
 temp[i] = 0; 
temp[0] = 1;
 //新数组长度加1,并第一个元素置赋值为1
 return temp;
 }
}

好像这块的题目已经把动态规划常规使用了,已经有点熟练了。

再回头看我第一个代码,说实话,有点幼稚😓

真厉害👍

———————————————————————————————————————————

class Solution {
    public int[] plusOne(int[] digits) {
        int s=0;//计数数
        int s1=0;//分身数
        for(int i=0;i<digits.length;i++){
            s=s*10+digits[i];//获取实际数字
        }
        s=s+1;
        s1=s;//复制,为了读取新数组的长度而不对s进行改变
        //(如果末尾有9可能长度会发生变化)
        int i=0;
        while(s1!=0){
             s1=s1/10;
             i++;
        }
        int[] d=new int[i];//建立新的数组,长度为变化后的位数
        int j=0;
        while(s!=0){
             d[j]=s%10;
             s=s/10;
             j++;
        }//将改变后的数字依次读入新数组,此时数组是反着的,因为%读数组从后读
        int x=0,y=d.length-1;
        while(x<y){
            int q=d[x];
            d[x]=d[y];
            d[y]=q;
            x++;
            y--;
        }//进行翻转
        return d;
        }
    
    }
    

此方法是我独立思考后完成的,虽然大部分例子都能正确实现,但是无法正确输出十位长度的数组。所以提交失败。、

class Solution {
    public int[] plusOne(int[] digits) {
        for(int i=digits.length-1;i>=0;i--){
            if(digits[i]!=9){
                digits[i]++;
                return digits;//出口1,改变后没有超出数组长度,如8->9;19->20
            }
            else{
                digits[i]=0;
            }
        }
        //执行到这里的,都是返回数组长度+1且第一位为1 其他全为0的数组,如99->100
        int[] digit=new int[digits.length+1];//新建数组默认为NULL
        digit[0]=1;
        return digit;//出口2,数组长度+1

    }
}

此方法完全正确,将题目分类考虑。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值