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;
}
};