Open azl397985856 opened 2 years ago
整个题可以看作是一个纯粹的数字相加的题,因为不管是数字还是数组,都是有序。
如1024这个数,不管是number类型的1024还是数组类型的 [1,0,2,4]都是一样的,不同的只是展现形式。
所以这道题的关键点在于采用哪种形式进行计算,以及如何转换为最终要的数组形式。其实计算反而不重要。
在解题时需要注意下溢出问题,这个题的测试用例是会有大数的,部分编程语言是不支持大数的 ( 如js的int32只支持18位以内的精确大数 ) ,所以计算要取巧。
采用古老而笨拙的按位进制法,即以numArray作为遍历条件,从最低位到最高位依次与k的最低位到最高位进行相加。
在相加的过程中有些东西需要注意:
function addToArrayForm(numArray: number[], k: number): number[] {
const KStr: string = String(k)
let numArrayIndex: number = numArray.length - 1
let KStrIndex: number = KStr.length - 1
let lastNum:number = 0
for(;numArrayIndex > -1; --numArrayIndex, --KStrIndex){
numArray[numArrayIndex] += (parseInt(KStr[KStrIndex]) || 0) + lastNum
lastNum = 0
if(numArray[numArrayIndex] > 9){
numArray[numArrayIndex] -= 10
lastNum = 1
}
}
if(KStrIndex > -1){
let overflowStr: string = String(parseInt(KStr.substring(0, KStrIndex + 1)) + lastNum)
KStrIndex = overflowStr.length - 1
lastNum = 0
const overflowArray: number[] = []
for(;KStrIndex > -1; --KStrIndex){
overflowArray.push(parseInt(overflowStr[KStrIndex]))
}
overflowArray.reverse()
numArray = [...overflowArray,...numArray]
}
if(lastNum === 1){
numArray = [1,...numArray]
}
return numArray
};
function addToArrayForm(numArray: number[], k: number): number[] {
const kArray: string[] = String(k).split("")
let kIndex: number = kArray.length - 1
let nIndex: number = numArray.length - 1
const resultArray: number[] = []
let lastNum:number = 0
for(;kIndex > -1 || nIndex > -1 ; --kIndex, --nIndex){
let result = (parseInt(kArray[kIndex]) || 0) + (numArray[nIndex] || 0) + lastNum
lastNum = 0
if(result > 9){
result -= 10
lastNum = 1
}
resultArray.push(result)
if(kIndex <= 0 && nIndex <= 0 && lastNum === 1){
resultArray.push(1)
}
}
return resultArray.reverse()
};
https://leetcode-cn.com/problems/add-to-array-form-of-integer/
对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]。
给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。
示例 1:
输入:A = [1,2,0,0], K = 34
输出:[1,2,3,4]
解释:1200 + 34 = 1234
示例 2:
输入:A = [2,7,4], K = 181
输出:[4,5,5]
解释:274 + 181 = 455
示例 3:
输入:A = [2,1,5], K = 806
输出:[1,0,2,1]
解释:215 + 806 = 1021
示例 4:
输入:A = [9,9,9,9,9,9,9,9,9,9], K = 1
输出:[1,0,0,0,0,0,0,0,0,0,0]
解释:9999999999 + 1 = 10000000000
提示:
1 <= A.length <= 10000
0 <= A[i] <= 9
0 <= K <= 10000
如果 A.length > 1,那么 A[0] != 0
模拟竖式 逐位相加
最后一位剩余进位别忘了加
Java Code:
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
ArrayList<Integer> kk = new ArrayList<>();
while(k != 0){
int tmp = k % 10;
k = k / 10;
kk.add(0,tmp);
}
int ml = num.length;
int kl = kk.size();
ArrayList<Integer> ans = new ArrayList<>();
int flag = 0;
while(ml != 0 && kl != 0){
int tmp = num[ml-1] + kk.get(kl-1) + flag;
if(tmp >= 10){
flag = 1;
tmp -= 10;
}
else
flag = 0;
ans.add(0, tmp);
kl--;
ml--;
}
if(ml != 0){
for(int i = ml-1; i>=0 ; i--){
int tmp = num[i];
if(flag == 1){
tmp++;
flag = 0;
}
if(tmp == 10){
tmp = 0;
flag = 1;
}
ans.add(0, tmp);
}
}else if(kl != 0){
for(int i = kl-1; i>=0 ; i--){
int tmp = kk.get(i);
if(flag == 1){
tmp++;
flag = 0;
}
if(tmp == 10){
tmp = 0;
flag = 1;
}
ans.add(0, tmp);
}
}
if(flag == 1){
ans.add(0, 1);
}
return ans;
}
}
复杂度分析
令 n 为数组长度。
java
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res = new LinkedList<>();
final int len = num.length;
for(int i = len - 1; i >= 0; i--) {
int sum = num[i] + k % 10;
k /= 10;
if(sum >= 10) {
k++;
sum -= 10;
}
res.add(0, sum);
}
for(; k > 0; k /= 10) {
res.add(0, k % 10);
}
return res;
}
}
//leetcode submit region begin(Prohibit modification and deletion)
//遍历nums[]转化为数值,再遍历返回数组
class Solution {
public List
把num先变成int 然后sum_int = k+num_int 再把sum_int变成sum_array
class Solution(object):
def addToArrayForm(self, num, k):
"""
:type num: List[int]
:type k: int
:rtype: List[int]
"""
## step0: corner case
if k == 0:
return num
## step1: change the array to number
n = len(num)
num_int = 0
for i in range(n):
num_int += num[i]*10**(n-1-i)
## step2: compute the sum
sum_int = num_int + k
sum_array = []
## step3: change the sum to array
while sum_int != 0:
quotient = sum_int//10
remainder = sum_int%10
## update sum array and int
sum_array.insert(0,remainder)
sum_int = quotient
return sum_array
时间 O(n^2)
空间 O(n)
int长度不够吧-------- 原始邮件 --------发件人: Xinyu Liu @.>日期: 2021年12月12日周日 18:45收件人: leetcode-pp/91alg-6-daily-check @.>抄送: chenyaohn @.>, Comment @.>主 题: Re: [leetcode-pp/91alg-6-daily-check] 【Day 1 】2021-12-12 - 989. 数组形式的整数加法 (Issue #1)
思路
把num先变成int 然后sum_int = k+num_int 再把sum_int变成sum_array
代码
class Solution(object):
def addToArrayForm(self, num, k):
"""
:type num: List[int]
:type k: int
:rtype: List[int]
"""
## step0: corner case
if k == 0:
return num
## step1: change the array to number
n = len(num)
num_int = 0
for i in range(n):
num_int += num[i]*10**(n-1-i)
## step2: compute the sum
sum_int = num_int + k
sum_array = []
## step3: change the sum to array
while sum_int != 0:
quotient = sum_int//10
remainder = sum_int%10
## update sum array and int
sum_array.insert(0,remainder)
sum_int = quotient
return sum_array
复杂度分析
时间 O(n^2)
空间 O(n)
—You are receiving this because you commented.Reply to this email directly, view it on GitHub, or unsubscribe.Triage notifications on the go with GitHub Mobile for iOS or Android.
@chenyaohn int长度不够吧-------- 原始邮件 --------发件人: Xinyu Liu @.>日期: 2021年12月12日周日 18:45收件人: leetcode-pp/91alg-6-daily-check @.>抄送: chenyaohn @.>, Comment @.>主 题: Re: [leetcode-pp/91alg-6-daily-check] 【Day 1 】2021-12-12 - 989. 数组形式的整数加法 (Issue #1)
思路
把num先变成int 然后sum_int = k+num_int 再把sum_int变成sum_array
代码
class Solution(object):
def addToArrayForm(self, num, k): """ :type num: List[int] :type k: int :rtype: List[int] """ ## step0: corner case if k == 0: return num ## step1: change the array to number n = len(num) num_int = 0 for i in range(n): num_int += num[i]*10**(n-1-i) ## step2: compute the sum sum_int = num_int + k sum_array = [] ## step3: change the sum to array while sum_int != 0: quotient = sum_int//10 remainder = sum_int%10 ## update sum array and int sum_array.insert(0,remainder) sum_int = quotient return sum_array
复杂度分析
时间 O(n^2)
空间 O(n)
—You are receiving this because you commented.Reply to this email directly, view it on GitHub, or unsubscribe.Triage notifications on the go with GitHub Mobile for iOS or Android.
其实这个偷懒了 应该是先把k变array 然后用carry 计算 sum of two array。长度应该是够的吧,至少submit是没有问题的。
var addToArrayForm = function(num, k) {
const res = [];
const n = num.length;
for (let i = n - 1; i >= 0; --i) {
let sum = num[i] + k % 10;
k = Math.floor(k / 10);
if (sum >= 10) {
k++;
sum -= 10;
}
res.push(sum);
}
for (; k > 0; k = Math.floor(k / 10)) {
res.push(k % 10);
}
res.reverse();
return res;
};
@chenyaohn 我看是@Liuxy94写的是python的代码,python3的话int自动就是long,所以应该是没问题
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
int carry = 0, a, b, c;
vector<int> result;
vector<int>::iterator iter = num.end();
while( iter != num.begin() || k > 0)
{
a = iter != num.begin() ? *(--iter) :0;
b = k % 10;
k /= 10;
c = (a + b + carry) % 10;
carry = (a + b + carry) / 10;
result.push_back(c);
}
if(carry == 1)
result.push_back(1);
std::reverse(result.begin(),result.end());
return result;
}
};
将K表示为数组,两个数组逐位相加。考虑进位。最后对数组取反。
class Solution:
def addToArrayForm(self, A: List[int], K: int) -> List[int]:
K = list(map(int,str(K)))
res = []
i,j = len(A)-1,len(K)-1
carry = 0
while i >= 0 and j >= 0:
res.append(A[i] + K[j] + carry)
res[-1],carry = res[-1] % 10, res[-1] // 10
i -= 1
j -= 1
while i >= 0:
res.append(A[i] + carry)
res[-1],carry = res[-1] % 10, res[-1] // 10
i -= 1
while j >= 0:
res.append(K[j] + carry)
res[-1],carry = res[-1] % 10, res[-1] // 10
j -= 1
if carry:
res.append(1)
return res[::-1]
/**
* 解题思路:先把题做出来,再考虑优化
* <p>
* 1.直观的看,应该属于大整数相加的问题
* 2.对num从后向前遍历,每次遍历中对k%10获得对应位数的值t,再对k/10
* 3.使得num[i]+t;考虑两种情况,<=9和>=10;如何是第一种情况,直接相加就行;如何是第二种情况,要考虑进位
* <p>
* 时间复杂度:O(n)
*
* @author My
* @date 2021/12/12
*/
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> temp = new ArrayList<>();
//用于进位
int carry = 0;
for (int i = num.length - 1; i >= 0; i--) {
int t = k % 10 + num[i] + carry;
if (t > 9) {
carry = 1;
} else {
carry = 0;
}
temp.add(t % 10);
k /= 10;
}
while (k != 0) {
int t = k % 10 + carry;
if (t > 9) {
carry = 1;
} else {
carry = 0;
}
temp.add(t % 10);
k /= 10;
}
if (carry != 0)
temp.add(carry);
List<Integer> res = new ArrayList<>();
for (int i = temp.size() - 1; i >= 0; i--) {
res.add(temp.get(i));
}
return res;
}
}
将数组和 k的对应项从右至左以此相加,进位时carry + 1;
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res = new ArrayList<>();
int carry = 0;
int l1 = num.length - 1;
while (l1 >= 0 || k != 0) {
int x = l1 < 0 ? 0 : num[l1];
int y = k == 0 ? 0 : k % 10;
int sum = x + y + carry;
res.add(sum % 10);
carry = sum / 10;
l1--;
k = k / 10;
}
if (carry != 0) res.add(carry);
Collections.reverse(res);
return res;
}
}
时间复杂度:O(N) 空间复杂度:O(1)
模拟一位位相加,处理进位,处理被加数、加数为0的情况
public class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> result = new ArrayList<Integer>();
int c = 0; //进位
for (int i = num.length-1; i >= 0; i--) { //倒着一位位相加
int a = num[i] + k%10 + c;
if (a > 9){
c = 1;
a -= 10;
if (i == 0 && (k/10 == 0)){ //存在进位且加数为0
result.add(a);
result.add(1);
break;
}
}else {
c = 0;
}
result.add(a);
k /= 10;
while (i==0 && k > 0){ //被加数为0加数不为0
int b = k%10 + c;
if (b > 9){
if(b==10 && (k/10 == 0)){ //进位
result.add(0);
result.add(1);
break;
}
b -= 10;
c =1;
}else {
c = 0;
}
result.add(b);
k /= 10;
}
}
Collections.reverse(result); //反转
return result;
}
}
复杂度分析
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
LinkedList<Integer> list = new LinkedList<>();
int i = num.length - 1;
int x = 0;
int add = 0;
while (i >= 0 || k > 0 || add == 1) {
if (i >= 0) x = num[i];
else x = 0;
int res = (x + k % 10 + add) % 10;
add = (x + k % 10 + add) / 10;
list.addFirst(res);
i --;
k /= 10;
}
return list;
}
}
时间复杂度: O(N) 空间复杂度: O(N)
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
lk = []
addOne = 0
while k:
k, m = divmod(k, 10)
lk.append(m)
ln = len(num); llk = len(lk)
res = [0 for _ in range(max(ln, llk)+1)]
num.reverse()
idx = 0
while idx < ln and idx < llk:
sum = num[idx] + lk[idx] + addOne
res[idx] = sum % 10
addOne = 0
if sum >= 10: addOne = 1
idx += 1
remain = num if ln > llk else lk
while idx < len(remain) or addOne:
if idx < len(remain): res[idx] += remain[idx]
res[idx] += addOne
addOne = 0
idx += 1
if res[idx] >= 10:
res[idx] %= 10
addOne = 1
if res[-1] == 0: res.pop()
res.reverse()
return res
JavaScript 思路: 1、遍历数组,从高到低,每项加上K 2、如果res >= 10, 将 k % 10,得到个位保留在num得当前下标,并计算Math.floot(k% 10),得到除个位外的数值res2 例如 num = [1,2,3,4], k= 1234 第一次循环:num[3] === 4, 4 + 1234 = 1238 k% 10 = 8,push到新数组 Math.floot(k% 10) = 123 令k= 123,继续循环 第二次循环:num[2] === 3, 3 + 123 = 126 k% 10 = 6,push到新数组 Math.floot(k% 10) = 12 令k= 12,继续循环 ... 最后得到数组[2,4,6,8] 需要注意的是,这里继续循环的条件不一定循环完整个数组,而是,循环完整个数据或循环完k,即 i >= 0 || k > 0 因为k不一定是和数组的length相同,当满足上面两个条件中的一个即可以继续循环
var addToArrayForm = function(num, k) {
const res = [];
const n = num.length;
for (let i = n - 1; i >= 0 || k > 0; --i, k = Math.floor(k / 10)) {
if (i >= 0) {
k += num[i];
}
res.push(k % 10);
}
res.reverse();
return res;
};
时间复杂度O(max(n,log k))
思路: 转换成两个vector,逐个按位相加,注意k可能比num长,因此要加上k比num长的部分
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> res;
int n=num.size();
for(int i=n-1;i>=0;i--){
int sum=num[i]+k%10;
k=k/10;
if(sum>=10){
sum=sum-10;
k++;
}
res.push_back(sum);
}
while(k){
res.push_back(k%10);
k=k/10;
}
reverse(res.begin(),res.end());
return res;
}
时间复杂度O(n) 空间复杂度O(1)
JavaScript 简单思路: 利用JS数组方法、字符串方法 数组-》字符串-》bigInt-》字符串-》数组
var addToArrayForm = function(num, k) {
let result = BigInt(num.join(''))
result += BigInt(k)
return String(result).split('')
};
这个地方需要注意要将字符串转成BigInt,不然会造成精度丢失。 时间复杂度度:O(n) => 数组join方法+字符串split方法
代码
public List<Integer> addToArrayForm(int[] num, int k) {
int len = num.length;
int lastNum = k;
LinkedList<Integer> ret= new LinkedList<>();
int i = len-1;
while(i >=0 || lastNum > 0){
if(i >= 0){
lastNum+=num[i];
}
ret.addFirst(lastNum%10);
lastNum/=10;
i--;
}
return ret;
}
复杂度分析
时间复杂度O(N);
/**
* @param {number[]} num
* @param {number} k
* @return {number[]}
*/
var addToArrayForm = function(num, k) {
const res = [];
const n = num.length;
for (let i = n - 1; i >= 0; --i) {
let sum = num[i] + k % 10;
k = Math.floor(k / 10);
if (sum >= 10) {
k++;
sum -= 10;
}
res.push(sum);
}
for (; k > 0; k = Math.floor(k / 10)) {
res.push(k % 10);
}
res.reverse();
return res;
};
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> ans = new ArrayList<Integer>();
int n = num.length;
for (int i=n-1; i>=0; i--){
int sum = num[i]+k%10;
k/=10;
if (sum>=10){
k+=sum/10;
sum%=10;
}
ans.add(sum);
}
for (;k>0;k/=10){
ans.add(k%10);
}
Collections.reverse(ans);
return ans;
}
}
时间复杂度:O(N)
空间复杂度:O(N)
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> ans = new ArrayList<Integer>();
int n = num.length;
for (int i=n-1; i>=0 || k>0; i--,k/=10){
if (i>=0){
k+=num[i];
}
ans.add(k%10);
}
Collections.reverse(ans);
return ans;
}
}
时间复杂度:O(N) O(max(n,logk))
空间复杂度:O(N)
从低位开始,将 A 的每一位与 K 的每一位相加,和大于10时,记录进位 “+1”,将和放到数组中,考虑 K 的长度大于 A 的情况,最后将数组翻转,返回结果
/**
* @param {number[]} num
* @param {number} k
* @return {number[]}
*/
var addToArrayForm = function(num, k) {
const res = [];
for(let i = num.length - 1; i >= 0; i--) {
let sum = num[i] + k % 10;
k = Math.floor(k / 10);
if(sum >= 10) {
k++;
sum -= 10;
}
res.push(sum);
}
for(; k > 0; k = Math.floor(k / 10)) {
res.push(k % 10);
}
res.reverse();
return res;
};
复杂度分析
// 91-day1-python
class Solution(object):
def addToArrayForm(self, num, k):
"""
:type num: List[int]
:type k: int
:rtype: List[int]
"""
i = len(num) - 1
carry = 0
res = []
while i >= 0 or k != 0:
x = num[i] if i >= 0 else 0
y = k % 10 if k != 0 else 0
sum = x + y + carry
res.append(sum % 10)
carry = sum // 10
i -= 1
k //= 10
if carry != 0: res.append(carry)
return res[::-1]
思路:从低位到高位依次计算,逐位将数字加在一起。任何时候,若加法的结果大于等于10,则进位为1。
代码:
class Solution:
def addToArrayForm(self, num: list[int], k: int) -> list[int]:
n = len(num)
ans = list()
carry = 0
for i in range(n):
res = k % 10
sum = num[n-i-1] + res + carry
carry = 0
k //= 10
if sum >= 10:
carry = 1
sum = sum % 10
ans.append(sum)
if k % 10 == 0 and k // 10 == 0 and carry == 1:
ans.append(1)
else:
while k % 10 != 0 or k // 10 != 0:
sum = k % 10 + carry
carry = 0
k //= 10
if sum >= 10:
carry = 1
sum = sum % 10
ans.append(sum)
if k % 10 == 0 and k // 10 == 0 and carry == 1:
ans.append(1)
ans.reverse()
return ans
时间复杂度:O(max(len(num), num_k)), num_k 是k的位数。
空间复杂度:O(max(len(num),` num_k)), num_k 是k的位数。
第一天,慢慢学。。。复杂的思路想不出来
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
return [int(s) for s in str(int("".join(list(map(str,num))))+k)]
思路:把整数k裁成数组,两个倒叙 ,数组length大的循环,位数相加
/**
* @param {number[]} num
* @param {number} k
* @return {number[]}
*/
var addToArrayForm = function(num, k) {
let kArr = k.toString().split('').map(item => parseInt(item));
let maxArr, minArr, a = 0;
if(kArr.length > num.length) {
maxArr = kArr.reverse();
minArr = num.reverse();
}else {
minArr = kArr.reverse();
maxArr = num.reverse();
}
const minLen = minArr.length
return maxArr.reduce((arr, item, index) => {
const n = index > minLen - 1 ? 0 : minArr[index];
arr.push((item + n + a) % 10);
a = Math.floor((item + n + a) / 10)
if(index === maxArr.length - 1 && a === 1) {
arr.push(1);
}
return arr;
}, []).reverse()
};
class Solution:
def addToArrayForm(self, A: List[int], K: int) -> List[int]:
return list(map(int,str(int(''.join(map(str,A))) + K)))
将数组从低位到高位加到k上,最后反转
语言支持:java
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res = new ArrayList<>();
for(int i = num.length-1;i >= 0|| k >0;i--,k/=10){
if(i>=0){
k+=num[i];
}
res.add(k%10);
}
Collections.reverse(res);
return res;
}
}
时间复杂度 O(max(n,log k)) , n为数组长度
空间复杂度 O(1)
思路: 使用arraylist做为新数组存最后的值,从后遍历数组中的每一位数,分别与k的个位相加,如果有进位则用一个carry存进位,每一位最后的值就是k的个位+A数组的值+carry,最后当k为0且A遍历完之后,如果carry有进位则要加入新数组,然后因为新数组是从个位加进新数组中的,最后的结果便要把它反过来。
代码:
public List
int sum = x + y + carry;
res.add(sum % 10);
carry = sum / 10;
l1--;
K = K / 10;
}
if (carry != 0) res.add(carry);
Collections.reverse(res);
return res;
}
时间复杂度:O(n) 空间复杂度:O(n)
1.列竖式法
2.低位到高位相加
3.考虑进位位
4.取反
class Solution(object):
def addToArrayForm(self, num, k):
"""
:type num: List[int]
:type k: int
:rtype: List[int]
"""
p1 = len(num) - 1
carry = 0
res = []
while p1 >= 0 or k != 0 or carry > 0:
adder1 = num[p1] if p1 >= 0 else 0
adder2 = k % 10
sum = adder1 + adder2 + carry
carry = 1 if sum >= 10 else 0
sum = sum - 10 if sum >= 10 else sum
res.append(sum)
p1 -= 1
k //= 10
return res[::-1]
/**
使用一个字母表示进位情况
*/
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer>list = new ArrayList<>();
int n = num.length;
int f = 0;
while(k>0||n>0){
int yu = k%10;
int sum = 0;
if(n>0)
sum = num[n-1]+yu+f;
else sum = yu+f;
f =0;
list.add(0,sum%10);
if(sum>9)
f = 1;
n--;
k = k/10;
}
if(f>0)
list.add(0,f);
return list;
}
}
从后往前加,然后翻转
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> ans = new ArrayList<Integer>();
int l = num.length ;
int m = 0;
for (int i = l-1 ; i >= 0 ; i--){
m = num[i] + k % 10 ;
k /= 10;
if (m >= 10){
k++;
m -=10;
}
ans.add(m);
}
for (; k > 0; k /= 10) {
ans.add(k % 10);
}
Collections.reverse(ans);
return ans;
}
}
复杂度分析 时间复杂度:$0(N)$ 空间复杂度:$0(N)$
class Solution:
def addToArrayForm(self, num, k) :
res = []
for n in num[::-1]:
k += n
res.insert(0, k%10)
k //= 10
while k:
res.insert(0, k%10)
k //= 10
return res
从末位相加即可。
实现的很差。放出来当个反例。
我在实现的时候眼睛紧盯着两个数组进行来进行构建,然后想要把答案存放在已有的两个数组之一。
但是这样的实现需要许多的边际确认,让代码变得十分复杂。 而且在最后的结果有进位的情况下,还是要对数组进行扩容,然后做 rotation。 得不偿失。
class Solution {
public:
vector<int> addToArrayForm(vector<int>& A, int K);
private:
vector<int> int_to_arr(int n);
};
vector<int> Solution::addToArrayForm(vector<int>& A, int K)
{
int carry;
int sum;
int idx_a, idx_b;
vector<int> a, b;
// edge case
if (K == 0)
return A;
// 1. convert K to array format.
vector<int> K_arr = int_to_arr(K);
// K can be greater than A
if (K_arr.size() > A.size()) {
a = A;
b = K_arr;
} else {
a = K_arr;
b = A;
}
// 2. Add small number to large number from the last digit to the highest digit.
// The result can have (A.lenght + 1) digits
idx_a = a.size() - 1;
idx_b = b.size() - 1;
carry = 0;
// add all digit
int len = a.size();
for (int i = 0; i < len; i++) {
sum = a[idx_a] + b[idx_b] + carry;
if (sum <= 9) {
b[idx_b] = sum;
carry = 0;
} else {
b[idx_b] = sum - 10;
carry = 1;
}
idx_a--;
idx_b--;
}
if (carry == 0)
return b;
if (idx_a == idx_b) {
b.insert(b.begin(), carry);
return b;
}
// add the last carry to b
while (carry != 0 && idx_b >= 0) {
sum = b[idx_b] + carry;
if (sum <= 9) {
b[idx_b] = sum;
carry = 0;
} else {
b[idx_b] = sum - 10;
carry = 1;
}
idx_b--;
}
if (carry) {
b.insert(b.begin(), carry);
}
return b;
}
vector<int> Solution::int_to_arr(int n)
{
int r;
vector<int> arr;
while (n != 0) {
r = n % 10;
n = n / 10;
arr.push_back(r);
}
reverse(arr.begin(), arr.end());
return arr;
}
复杂度分析
function fn(arr, number) { let a1 = Number(arr.join('')); let result = BigInt(a1) + BigInt(number) return String(result).split('') }
/**
* @param {number[]} num
* @param {number} k
* @return {number[]}
*/
var addToArrayForm = function(num, k) {
const res = [];
const n = num.length;
for (let i = n - 1; i >= 0 || k > 0; --i, k = Math.floor(k / 10)) {
if (i >= 0) {
k += num[i];
}
res.push(k % 10);
}
res.reverse();
return res;
};
复杂度:数组长度O(n)
思路:,将num和k从个位起逐位相加,最终然后反转res即可。 for i in range(len(num)-1,-1, -1): A = num[i] + k % 10 k = k // 10 if A >= 10: k += 1 res.append(A%10) while k >0: res.append(k%10) k = k // 10 res.reverse() return(res) 时间复杂度O(n)
class Solution {
// 思路: 1、将数组的最后一个元素和k的个位开始相加,
// 2、大于10 就向前进一位(k的前一位 + 1)
// 3、 重复以上步骤直到数组和k的位数结束
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> rest = new LinkedList<>();
int len = num.length - 1;
for(int i = len;i >= 0;i--) {
int total = num[i] + k % 10;
//取 除过后一位的前面的值
k /= 10;
if(total >= 10) {
//大于10,则前面的值需要进1
k++;
total = total % 10;
}
rest.add(total);
}
while(k > 0) {
rest.add(k % 10);
k /=10;
}
Collections.reverse(rest);
return rest;
}
}
class Solution {
// 思路: 1、将数组的最后一个元素和k的个位开始相加,
// 2、大于10 就向前进一位(k的前一位 + 1)
// 3、 重复以上步骤直到数组和k的位数结束
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> rest = new LinkedList<>();
int len = num.length - 1;
for(int i = len;i >= 0;i--) {
int total = num[i] + k % 10;
//取 除过后一位的前面的值
k /= 10;
if(total >= 10) {
//大于10,则前面的值需要进1
k++;
total = total % 10;
}
rest.add(total);
}
while(k > 0) {
rest.add(k % 10);
k /=10;
}
Collections.reverse(rest);
return rest;
}
}
模拟竖式计算
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res = new LinkedList<>();
int idx = num.length-1;
int carry = 0;
while (idx >= 0 || k > 0) {
int x = idx >= 0 ? num[idx] : 0;
int y = k > 0 ? k % 10 : 0;
int sum = x+y+carry;
res.add(0, sum%10);
carry = sum / 10;
idx--;
k /= 10;
}
if (carry == 1) {
res.add(0, 1);
}
return res;
}
}
复杂度分析
思路与解法
逐位加;
反向存,最后reverse,不然正向存,每次add数组都得挪位;
心得
第一次fail了因为大意了,这题要注意num和k的长短不一,不能一个for on num解决;
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
int carry = 0, i = num.length - 1;
List<Integer> res = new ArrayList<>();
while(i >= 0 || k > 0 || carry > 0){
int left = i >= 0?num[i]:0;
i--;
int right = k % 10;
k = k / 10;
int sum = left + right + carry;
res.add(sum % 10);
carry = sum / 10;
}
Collections.reverse(res);
return res;
}
}
k因为是常数,其实其长度可以忽略。
time: O(Math.max(num.length, Math.log10(k)+1)) space: O(1),不算结果
思路:先把数字k转化为数组,然后比较两个数组的长度,用0将较短的数组填充到与长数组等长,然后进行等位相加 class Solution(object): def addToArrayForm(self, num, k):
L_k = []
while (k / 10 != 0):
L_k.append(k % 10)
k=int(k / 10)
num= list(reversed(num))
ln=len(num)
lk=len(L_k)
if lk>ln:
q=[0]*(lk-ln)
num.extend(q)
elif lk==ln:
num.append(0)
else:
q=[0]*(ln-lk)
L_k.extend(q)
for i in range(len(num)-1):
w=num[i] + L_k[i]
num[i]=w%10
num[i+1]=int(w/10)+num[i+1]
if num[len(num)-1]==0:
num=num[:-1]
num = list(reversed(num))
return num
时间复杂度O(n)
class Solution(object): def addToArrayForm(self, num, k): """ :type num: List[int] :type k: int :rtype: List[int] 思路:类似于大数相加,先把数字k转化为数组, """ L_k = [] while (k / 10 != 0): L_k.append(k % 10) k=int(k / 10) num= list(reversed(num)) ln=len(num) lk=len(L_k) if lk>ln: q=[0](lk-ln) num.extend(q) elif lk==ln: num.append(0) else: q=[0](ln-lk) L_k.extend(q)
for i in range(len(num)-1):
w=num[i] + L_k[i]
num[i]=w%10
num[i+1]=int(w/10)+num[i+1]
if num[len(num)-1]==0:
num=num[:-1]
num = list(reversed(num))
return num
新增temp数组存上次计算的进位1,每次取三个数组的末位数进行相加,取余数存进res数组中,直到三个数组都空的时候,计算结束
var addToArrayForm = function(num, k) {
let cur = String(k).split('');
let res = [];
let temp = []
while(num.length > 0 || cur.length > 0 || temp.length > 0) {
let a = Number(num.pop() || 0);
let b = Number(cur.pop() || 0);
let c = Number(temp.pop() || 0);
if(a + b + c >= 10) {
res.unshift((a+ b + c)%10);
temp.push(1);
} else {
res.unshift(a+b+c)
}
}
return res
};
-时间复杂度:O(n),其中n为num和k的最大长度 -空间复杂度:O(n),其中n为num和k的最大长度或最大长度+1
把数组A从后开始循环,整数K也从个位数开始,把两个相加, 如果大于10有进位,把进位存carry变量,结果res存数组。 每次循环把carry一起相加,最后反转res数组。
var addToArray = function(A, K) {
const res = [];
let i = A.length - 1, carry = 0;
while (i >=0 || K != 0) {
const x = i >= 0 ? num[i] : 0;
const y = K != 0 ? K % 10 : 0;
const sum = x + y + carry;
res.push(sum % 10);
carry = Math.floor(sum / 10);
i--;
K = Math.floor(K / 10);
}
if (carry) res.push(carry);
return res.reverse();
}
复杂度分析
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> result = new ArrayList<Integer>();
int len=num.length-1;
for (int i=len; i>=0;i--){
int temp=num[i]+k;
result.add(temp%10);
k=temp/10;
}
while(k!=0){
result.add(k%10);
k=k/10;
}
Collections.reverse(result);
return result;
}
复杂度分析
将其中一个变为数组,之前两个都变数组,纠结怎么获取索引,现在另一个每次自处自动补零。
var addToArrayForm = function(num, k) { let s = []; let flag = false; let nl = num.length; while(nl != 0 || k != 0) { let a = 0, b = k % 10 ; if(nl !== 0) a = num[--nl]; k = parseInt(k/10);
let ans = a + b;
if(flag) {
ans += 1;
flag = false;
}
if( ans >= 10) flag = true;
s.push(ans % 10);
}
if(flag) s.push(1);
return s.reverse();
};
模拟真正的加法计算过程
从后往前依次逐位相加,如果 >=10 则进位
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> result = new ArrayList<>();
int len = num.length;
for (int i = len - 1;i >= 0;i--){
int a = num[i] + k % 10;
k /= 10;
// 如果和 > 10,需要进位
if (a >= 10 ){
k++;
}
result.add(a % 10);
}
// 上面循环做完,只求了结果后len位的值,由于可能进位,所以k可能还有很多位
for (; k > 0; k /= 10) {
result.add(k % 10);
}
Collections.reverse(result);
return result;
}
var addToArrayForm = function(num, k) {
const res = [];
const n = num.length;
for (let i = n - 1; i >= 0; --i) {
let sum = num[i] + k % 10;
k = Math.floor(k / 10);
if (sum >= 10) {
k++;
sum -= 10;
}
res.push(sum);
}
for (; k > 0; k = Math.floor(k / 10)) {
res.push(k % 10);
}
res.reverse();
return res;
};
989. 数组形式的整数加法
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/add-to-array-form-of-integer/
前置知识
题目描述
给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。
示例 1:
输入:A = [1,2,0,0], K = 34 输出:[1,2,3,4] 解释:1200 + 34 = 1234 示例 2:
输入:A = [2,7,4], K = 181 输出:[4,5,5] 解释:274 + 181 = 455 示例 3:
输入:A = [2,1,5], K = 806 输出:[1,0,2,1] 解释:215 + 806 = 1021 示例 4:
输入:A = [9,9,9,9,9,9,9,9,9,9], K = 1 输出:[1,0,0,0,0,0,0,0,0,0,0] 解释:9999999999 + 1 = 10000000000
提示:
1 <= A.length <= 10000 0 <= A[i] <= 9 0 <= K <= 10000 如果 A.length > 1,那么 A[0] != 0