超详细小白做题思路全解LeetCode989.组形式的整数加法

989. 数组形式的整数加法

题目

整数的 数组形式  num 是按照从左到右的顺序表示其数字的数组。

  • 例如,对于 num = 1321 ,数组形式是 [1,3,2,1] 。

给定 num ,整数的 数组形式 ,和整数 k ,返回 整数 num + k 的 数组形式 。

示例 1:

输入:num = [1,2,0,0], k = 34
输出:[1,2,3,4]
解释:1200 + 34 = 1234

示例 2:

输入:num = [2,7,4], k = 181
输出:[4,5,5]
解释:274 + 181 = 455

示例 3:

输入:num = [2,1,5], k = 806
输出:[1,0,2,1]
解释:215 + 806 = 1021

提示:

  • 1 <= num.length <= 104
  • 0 <= num[i] <= 9
  • num 不包含任何前导零,除了零本身
  • 1 <= k <= 104

思路&解题过程

题目要求将一个以组数形式表示的数num,和另一个整数k,进行加法运算 得到的结果再用数组形式表

[错误方法 1] 首先想到的是: 先将数组形式的num从个位开始往前处理 用每个位子上的数字乘以相应10的倍数(使用pow方法表示10的几次方)

再全部加到一起,得到int型的num(用m表示) 然后计算m+k,得到sum 再把sum用%10处理,逐位顺序存储在ans数组中

(由于加法后可能进位,ans数组长度不确定,使用push_back方法) 最后使用reverse反转结果数组ans(上一步从个位开始存储的,所以需要反转一下得到正确顺序的数组)

再返回ans

代码如下:

class Solution {

public:

    vector<int> addToArrayForm(vector<int>& num, int k) {

        int len = num.size();

        int m = 0,cnt=0;

        vector<int> ans;

        for(int i = len-1 ;i >= 0;i--){

            m +=num[i]*pow(10, len-1-i);      

        }

        int sum = m+k;

        while(sum>0){

            ans.push_back(sum % 10); 

            //ans数组没有初始化长度不能用索引 ans[cnt++]=sum%10;

            //改用.push_pack方法加入元素

            sum /= 10;//去掉最后一位

        }

        

        reverse(ans.begin(), ans.end());

        return ans;

    }

};

运行后发现,出现越界错误

返回查看题目,发现题设中1 <= num.length <= 10^4

那么这个数字可以有1000位辣么长,pow在10的10次方就越界了,不能用这个


没有替代方法可以求出num实际表示数而不产生越界

那么我们需要换个思路

像加法竖式类似 进行末位相加 采取进位措施


具体思路:

从个位开始,也就是num数组的最后一个元素开始

加上k得到一个新的值s(例如,num的个位为3,k为29,那么s=32)

!:这里需要注意的是与竖式计算相似,但没有采用个位加个位的方法

那么s的个位肯定就是最后num+k的个位,于是将s%10取最后一位(2)存入结果数组中

那么s的剩余值(3)应该加入num十位中,为使程序循环,把s赋值给k

可以理解为个位处理完后被消灭,随i++,num的十位变成了个位

再进行一个+k的循环操作

最后把这个数组反转,返回结果

[错误代码 2]

class Solution {

public:

    vector<int> addToArrayForm(vector<int>& num, int k) { 

        vector<int> ans;

        int n = num.size();

        int s;

        for(int i = n -1 ; i>=0 ; i--){//从个位往前遍历数字

            s = num[i] + k;//末位+k

            ans.push_back(s%10);//将计算结果的最后一位存入结果数组

            s /= 10;//砍掉最后一位

            k = s;//程序连贯,将处理过的s视为k,送入下一循环

        }

        reverse(ans.begin(), ans.end());

        return ans;

    }

};

运行完发现,进位后的第一位(从左往右)也就是最后剩下的k,没有被输出,于是在反转数组前加上以下代码

[错误代码 3]

    if(k){
        ans.push_back(k);
    }

再次运行,发现在测试用例

输入num =[0] k =10000时报错,输出结果为[10000,0]

那么意味着我们每有考虑到num和k相差很大时,k的处理

不能一股脑直接把k塞进数组里

同样要逐位处理

所以把上面的代码改为下面的代码

while(k){

    ans.push_back(k%10);

    k /= 10;

}

运行通过!!!

完整代码在下面!!!


复杂度

  • 时间复杂度:O(max(n,logk))
  • 空间复杂度:O(1)

Code

class Solution {
public:
    vector<int> addToArrayForm(vector<int>& num, int k) { 
        vector<int> ans;
        int n = num.size();
        int s;
        for(int i = n -1 ; i>=0 ; i--){//从个位往前遍历数字
            s = num[i] + k;//末位+k
            ans.push_back(s%10);//将计算结果的最后一位存入结果数组
            s /= 10;//砍掉最后一位
            k = s;//程序连贯,将处理过的s视为k,送入下一循环
        }
      
        while(k){
            ans.push_back(k%10);
            k /= 10;
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值