Open azl397985856 opened 2 years ago
思路: 先用reduce计算num对应数值, 然后加上k后转成iterable的str对象 再利用map从高位到低位依次转成整数, 最后转成list class Solution: def addToArrayForm(self, num: List[int], k: int) -> List[int]: return list(map(int, str(k+reduce(lambda a, b: a*10+b, num))))
因为A.length最大为10000,所以不能采用类型转换来做,只能采用模拟的办法
设置i作为进位,若对应位与i一起相加后大于10,说明有进位,就将i设置为1,结果对10取余;若小于10则直接进行下一高位的计算。
我设置的条件时num和k同时大于0,若跳出说明至少有一个参数已经到了最高位了,那么未到最高位的参数就以基本相同的思路继续计算。
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
int key = num.size()-1;
int i = 0;
while(key>=0 && k){
num[key] = i + num[key] + k%10;
i = 0;
if(num[key] >= 10){
i = 1;
num[key] %= 10;
}
k /= 10;
key--;
}
//当k比num长时
while(k){
int sum = k%10+i;
num.insert(num.begin(),sum%10);
i = sum/10;
k /= 10;
}
//当num比k长时
while(key>=0){
num[key] = i + num[key] + k%10;
i = 0;
if(num[key] >= 10){
i = 1;
num[key] %= 10;
}
key--;
}
if(i) num.insert(num.begin(),1);
return num;
}
};
复杂度分析
时间复杂度:O(max(numlen,klen)) (numlen为num的长度,klen为k的长度);
空间复杂度:O(1)
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> res;
int n = num.size();
for(int i = n - 1; i >= 0 || k; i --)
{
if(i >= 0)
k += num[i];
res.push_back(k % 10);
k /= 10;
}
reverse(res.begin(), res.end());
return res;
}
};
首先得想法是把两个数加起来,再依次取出个位,添加进结果中,但是这样会溢出。 于是选择从后往前遍历数组,末尾数字相加后添加进结果集中,同时判断一下有没有进位。 最后还要看看 k 和进位等于 0 没有,如果没有还要继续添加进结果集中。 添加数字时,要保证顺序,所以每次插入在数组开头,也就是 0 的索引位置,使用 LinkedList 而不是 ArrayList 会提升插入的性能
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res=new LinkedList<>();
int carry=0;
for(int i=num.length-1; i>=0; i--){
int sum=0;
sum=num[i]+k%10+carry;
k/=10;
carry=sum/10 > 0 ? 1:0;
sum%=10;
res.add(0, sum);
}
while(k!=0){
int sum=k%10+carry;
carry=sum/10 > 0 ? 1:0;
sum%=10;
k/=10;
res.add(0, sum);
}
if(carry!=0){
res.add(0, 1);
}
return res;
}
}
复杂度分析
思路
本来是想着是把两个数加起来,再依次取出个位,添加进结果中,但是这样会溢出。
于是选择从后往前遍历数组,末尾数字相加后添加进结果集中,同时判断一下有没有进位。
最后还要看看 k 和进位等于 0 没有,如果没有还要继续添加进结果集中。
最后需要Collections.reverse(res);反转链表
<加法模板>
while ( A 没完 || B 没完)
A 的当前位
B 的当前位
和 = A 的当前位 + B 的当前位 + 进位carry
当前位 = 和 % 10;
进位 = 和 / 10;
判断还有进位吗
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];//最左边,也就是前面没有数了,就附上0
int y = k == 0 ? 0 : k % 10;//取余->取出个位数 ////最左边,也就是前面没有数了,就附上0
int sum = x + y + carry;
carry = sum / 10;
res.add(sum % 10);
l1--;
k = k / 10;
}
//最左边的carr可能还有,判断是不是0
if (carry != 0) {
res.add(carry);
}
Collections.reverse(res);
return res;
}
}
复杂度分析
- 时间复杂度:O(N)
- 空间复杂度:O(1)
①将数组A转成整数,再将整数A和K进行运算,再将运算结果化为数组
②利用数组进行运算
通过取余和整除的方法,把k的最低位取出与数组的最低位进行和运算;在进行加和的时候因为有可能超出9,要考虑进位,可考虑把进的那一位直接加在k上;由于k和数组的相对长度不知道,所以在第一次循坏完数组之后,要再循环一次k的剩余位数。
var addToArrayForm = function (num, k) {
const numLen = num.length;
let res = [];
for (let i = numLen - 1; i >= 0; i--) {
let sum = num[i] + k % 10;
k = Math.floor(k / 10);
if (sum > 9) {
k++;
sum -= 10;
}
res.push(sum);
}
for (; k > 0; k = Math.floor(k / 10)) {
let sum = k % 10;
res.push(sum);
}
res.reverse();
return res;
};
复杂度分析
把数字转换成数组,对应位相加传入新数组,考虑进位情况
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
list_k = []
while k > 0:
temp = k%10
list_k.insert(0,temp)
k-=temp
k/=10
res = []
add_up = 0
while list_k and num:
i = list_k.pop()+num.pop()
if i+add_up< 10:
res.insert(0,int(i+add_up))
add_up = 0
else:
res.insert(0,int(i-10+add_up))
add_up = 1
while list_k and not num:
i = list_k.pop()
if i+add_up< 10:
res.insert(0,int(i+add_up))
add_up = 0
else:
res.insert(0,int(i-10+add_up))
add_up = 1
while num and not list_k:
i = num.pop()
if i+add_up< 10:
res.insert(0,int(i+add_up))
add_up = 0
else:
res.insert(0,int(i-10+add_up))
add_up = 1
while not num and not list_k:
if add_up == 1:
res.insert(0,1)
return res
复杂度分析
先把k与个位相加。从低到高逐位检查是否大于等于十。如果是,则算出carry on (n // 10) 并加入到前一位,以及当前位保留的值 (n %= 10)。到了最高位如果还大于等于10 则需要在前面手动增加位数,并继续进行计算carry on 和保留值。
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
num[-1] += k
i = len(num) - 1
while i > 0 and num[i] > 9:
num[i-1] += num[i] // 10
num[i] %= 10
i -= 1
while num[0] > 9:
num = [num[0] // 10] + num
num[1] = num[1] % 10
return num
Time Complexity: O(len(num))
Space Complexity: O(1)
v1 笨方法,先把list转成字符串,字符串转成int,相加之后结果转字符串,字符串拆开成list,害
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
num = [str(i) for i in num]
num = "".join(num)
num = int(num)
num = str(num+k)
num = [int(i) for i in num]
return num
复杂度分析
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
int n = num.size() - 1;
int cur = k;
vector<int> result;
while(n >= 0 || cur)
{
if(n>=0)
{
cur = cur + num[n];
}
result.push_back(cur%10);
cur = cur / 10;
n--;
}
reverse(result.begin(), result.end());
return result;
}
};
我是从末位数的方面来考虑,因为需要进行整数的加法,那么k+arr[len-1]%10的值一定是最终和的末位数,那么便从数组的最后一位开始遍历,与k进行相加并取模放入ans数组(因为是从末尾开始,因此需要insert插入到ans的首位)
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> ans;
int len = num.size()-1;
for(int i=len;i>=0;i--){
k=k+num[i];
ans.insert(ans.begin(),k%10);
k/=10;
}
// 此处的处理是为了防止k过大的情况
if(k){
while(k>9){
ans.insert(ans.begin(),k%10);
k/=10;
}
ans.insert(ans.begin(),k);
}
return ans;
}
};
时间复杂度:O(n)(主要花销在遍历)
空间复杂度:O(n)(开辟了新的数组用于存储结果)
iterate the array and integer from right to left, sum up and store in the ArrayList. use a carry variable to store the tens. reverse the ArrayList in the end.
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
int len = num.length - 1;
List<Integer> res = new ArrayList<>();
int carry = 0;
while(len >= 0 || k != 0){
int x = len < 0 ? 0 : num[len];
int y = k == 0 ? 0 : k % 10;
int sum = carry + x + y;
res.add(sum % 10);
carry = sum / 10;
len--;
k = k / 10;
}
if (carry > 0) res.add(1);
Collections.reverse(res);
return res;
}
}
复杂度分析
考虑到需要进位,需要的位数可能发生变化,新增一个List储存结果
双指针遍历两个整数,使用一个add记录进位
类似题目有大数加减法
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
int i = num.length - 1;
int j = 0;
int add = 0;
ArrayList<Integer> resList = new ArrayList<>();
while(i >= 0 || k > 0 ||add != 0){
int x = i < 0 ? 0 : num[i];
int y = k == 0 ? 0 : k % 10;
int result = x + y + add;
add = result /10;
resList.add(result % 10);
i--;
k = k / 10;
}
Collections.reverse(resList);
return resList;
}
}
空间:使用了一个新建List保存结果,List大小为num[]或k的位数 O(n)
时间:遍历一遍num[] 长度n或k的位数m中最大的一个,O(n)
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
number = 0
for n in num:
number = number * 10 + n
total_num = number + k
num_list = []
while total_num >= 10:
temp = total_num % 10
total_num = total_num // 10
num_list.append(temp)
num_list.append(total_num)
return num_list[::-1]
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
total = 0
index = 0
for n in num[::-1]:
total += (10 ** index) * n
index += 1
total += k
res = []
for digit in str(total):
res.append(int(digit))
return res
class Solution {
public:
vector
while(i >= 0 || k != 0)
{
int n1 = i >= 0 ? num[i] : 0;
int n2 = k >= 0 ? k % 10 : 0;
int value = n1 + n2 + carry;
vec.push_back(value % 10);
carry = value / 10;
--i;
k = k / 10;
}
if(carry != 0)
vec.push_back(carry);
reverse(vec.begin(), vec.end());
return vec;
}
};
https://leetcode-cn.com/problems/add-to-array-form-of-integer/
对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]。
给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/add-to-array-form-of-integer 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
res = []
for i in range(len(num) - 1, -1, -1):
add = num[i] + k % 10 # k包含进位信息
k = k // 10
if add >= 10:
add -=10
k += 1 # 将进位1加到k上
res.append(add % 10)
# 若k不是零
while k != 0:
res.append(k % 10)
k = k // 10
return res[::-1]
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> res;
for(int i = num.size() - 1; i >= 0; i--){
int add = num[i] + k % 10;
k /= 10;
if (add >= 10){
k++;
add = add - 10;
}
res.push_back(add % 10);
}
while (k != 0){
res.push_back(k % 10);
k /= 10;
}
reverse(res.begin(), res.end());
return res;
}
};
思路 1 定义常量n,同时遍历两个数组,从末尾开始遍历,条件是两个指针的索引同时大于等于0, 将对应索引上的值相加再加上n与10取模值, 取模结果记入集合中,整除结果赋值给n
2 1的循环跳出,说明此时其中一个数组已经到头了,遍历当前索引大于0的数组,将当前的索引的值 加上n 添加到集合,剩下的值依次加入到集合,循环结束,输出结果。 3.最后一个输出的数若取整为1要进一位。
关键点 循环的条件,取模,取整 集合容器的选取:方便从头部插入数据的集合,链表 边界问题:最后一个输出的数若取整为1要进一位
代码 语言支持:Java Java Code:
class Solution {
public List
复杂度分析
令 n 为数组长度。
时间复杂度:O(n) n为两个数组中较长的长度 空间复杂度:O(n)
模拟加法:A + k
当前位 = (A的当前位 + k) % 10
当前位的进位 = (A的当前位 + k) // 10
这样可将 k 整体看作为进位,省略了变量carry
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
res = []
while num or k: # 若num未遍历完,【或】k未遍历完(k>0)
x = (num.pop() if num else 0) + k # 若num未遍历完,pop一下;否则,设为0
k = x // 10
res.append(x%10)
return res[::-1]
复杂度分析
class Solution {
public List addToArrayForm(int[] num, int k) {
List res = new ArrayList();
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; }
res.add(sum); }
for (; k > 0; k /= 10) {
res.add(k % 10); }
Collections.reverse(res);
return res; } }
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
k=[int(x) for x in str(k)]
i=len(num)-1
j=len(k)-1
carry=0
result=deque([])
while i>=0 or j>=0:
a=num[i] if i >=0 else 0
b=k[j] if j>=0 else 0
s=a+b+carry
carry=s//10
result.appendleft(s%10)
i-=1
j-=1
if carry != 0:
result.appendleft(carry)
return result
Time: O(n) Space: O(n)
判断k是否倒序遍历数组,在与k % 10 相加 之后在将k /10 , 在判断结果>10 ,++k并且将结果-10,在存入数组中 同时k的位数会大于数组长度,需要加一个循环插入大于的数据
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> results = vector<int>();
int listSize = num.size();
int temp;
for (int i = listSize - 1; i >= 0; i--)
{
if (k != 0)
{
temp = num[i] + k % 10;
k /= 10;
if (temp >= 10)
{
++k; // 进位
temp -= 10;
}
}
else
{
temp = num[i];
}
results.push_back(temp);
}
while (k > 0)
{
results.push_back(k % 10);
k /= 10;
}
reverse(results.begin(), results.end());
return results;
}
思路
逐位相加,每次记录进位carry,直到k和num的每一位数都处理完,最后反转结果数组
代码
class Solution(object):
def addToArrayForm(self, num, k):
"""
:type num: List[int]
:type k: int
:rtype: List[int]
"""
i = len(num) - 1
n = []
carry = 0
while k or (i >= 0) or carry:
if i >= 0:
sum_ = num[i] + k % 10 + carry
else:
sum_ = k % 10 + carry
n.append(sum_ % 10)
carry = sum_ // 10
k //= 10
i -= 1
n.reverse()
return n
复杂度
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res = new ArrayList<Integer>();
for (int i = num.length - 1; i >= 0; i--){
int sum = num[i] + k % 10;
k /= 10;
if (sum >= 10){
k++;
sum -= 10;
}
res.add(sum);
}
while (k > 0){
res.add(k % 10);
k /= 10;
}
Collections.reverse(res);
return res;
}
}
// 使用BigInt偷个懒
var addToArrayForm = function(A, K) {
let N = '';
A.forEach( e =>{
N = N+e
})
return String(BigInt(N) + BigInt(K)).split('').map(e => Number(e))
};
1.数组A转换成整数, 2.A和K再求和 3.每位数分开 4.再生成新数组
JavaScript:
Const getNewSum =(A,K)=>{ return(Number( A.join(,))+K).split(,) }
时间复杂度 O(n)
逐位相加,如果大于9,就要进位
var addToArrayForm = function(num, k) {
k = String(k).split('')
var length = Math.max(num.length, k.length)
var res = new Array(length).fill(0)
for (let index = length-1; index >= 0; index--) {
var a = num.length > 0 ? num.pop() : 0
var b = k.length > 0 ? k.pop() : 0
var sum = res[index] + a + +b
res[index] = sum % 10
if (sum > 9) {
if (index-1 >= 0) {
res[index - 1] = 1
} else {
res.unshift(1)
}
}
}
return res
};
时间复杂度:O(n) 空间复杂度:O(n)
结论:大整数算不了。估计这就是题的意义之一,大整数如何存储和加减运算
结论:想想觉得蠢,应该不至于。
思路偷到了:从num的最后一位开始加,加完了个位存起来,突突突接着往前加。
脑子: ‘我会了‘,手:’你会个屁‘。
var addToArrayForm = function(num, k) {
const n = num.length;
const res = []
for(let i = n - 1; i >=0 || k != 0; i--){
if(i >=0){
// 相加
k += num[i]
}
// 取值
res.push(k % 10)
// 下一个k
k = Math.floor(k / 10)
}
res.reverse()
return res
};
时间: O(n)
空间: O(1)
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> num1;
int n= num.size();
for(int i = n-1; i>=0; i--) // vector数组是从左往右的,num[0]是最左边的数
{
int sum = num[i]+k%10; // 逐位相加
k /= 10;
if(sum>=10)
{
k++; // 进位加1
}
num1.push_back(sum%10);
sum = 0;
}
while(k>0) // 考虑整数k比数组 位数多 的情况
{
num1.push_back(k%10);
k /= 10;
}
reverse(num1.begin(), num1.end()); // 数组反转
return num1;
}
};
时间复杂度:O(n)
空间复杂度:O(1)
对于非负整数 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
模拟加法的过程即可
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
//因为num的位数可以有10000位,所以肯定是超过了int,或者long的,那么只能通过数组按位计算
//每一位的值 = num数组在这一位上的值 + k数组在这一位上的值 + 前一位的进位
LinkedList<Integer> res = new LinkedList<>();
int carry = 0;
for(int i = num.length - 1; i >= 0; i--){
//拿当前k的最后一位 Take the last digit of the current k
int kLastDigital = k % 10;
//sum of the add
int sumOfAdd = num[i] + kLastDigital + carry;
//注意是头插到结果list中
res.addFirst(sumOfAdd % 10);
//处理carry和k
carry = sumOfAdd / 10;
k = k / 10;
}
//如果k提前结束了,那没有关系,后面全部加的都是0
//但如果是num先结束了,k还有剩余,那还要把k给处理完
while(k != 0){
int kLastDigital = k % 10;
int sumOfAdd = kLastDigital + carry;
//注意是头插到结果list中
res.addFirst(sumOfAdd % 10);
//处理carry和k
carry = sumOfAdd / 10;
k = k / 10;
}
//最后还要检查carry里面还有没有数,如果有的话,加进去
if(carry!=0){
res.addFirst(carry);
}
return res;
}
}
时间复杂度:$O(n)$
空间复杂度:$O(n)$
class Solution {
public List
逐位相加,记录进位,计算后头插到结果数组
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> res = new ArrayList<>();
int carry = 0;
for(int i = num.length - 1;i >= 0 || k > 0;i--){
int dec = (k % 10) + carry;
dec += i >= 0 ? num[i] : 0;
k = k / 10;
carry = 0;
if(dec >= 10){
carry = 1;
dec = dec % 10;
}
res.add(0,dec);
}
if(carry != 0) res.add(0,1);
return res;
}
}
空间O(N) 时间O(N)
模拟竖式计算,新的一期打算开始试着用Java实现,自己不习惯Java,思路还是在Python上的思路,感觉实现得有点粗糙
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
ArrayList<Integer> klist=new ArrayList<>();
ArrayList<Integer> nums=new ArrayList<>();
for (int n:num)
{
nums.add(n);
}
while (k>0)
{
klist.add(0,k%10);
k=k/10;
}
int a=klist.size();
int b=nums.size();
if(a<b)
{
for (int i1=0;i1<b-a;i1++)
{
klist.add(0,0);
}
}
else if(b<a)
{
for (int i2=0;i2<a-b;i2++)
{
nums.add(0,0);
}
}
ArrayList<Integer> ans=new ArrayList<>();
int saving=0;
for (int i=nums.size()-1;i>=0;i--)
{
int tmp=saving+klist.get(i)+nums.get(i);
ans.add(0,tmp%10);
saving=tmp/10 ;
}
if(saving>0)
{
ans.add(0,saving);
}
return ans;
}
}
时间:O(max(m,n)) 空间:O(n)
从num的最后一位往前遍历,同时维护carry进位。循环条件是num下标合法或者k大于0才结束,那么累加的时候就要注意数组num下标的合法性。最后退出循环后再检查一下carry,防止漏加。将最后结果reverse后返回即可。
C++ Code:
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> res;
int carry = 0;
for (int i = num.size() - 1, j = 0; i >= 0 || k > 0; --i, ++j) {
auto tmp = (i >= 0 ? num[i] : 0) + k % 10 + carry;
res.emplace_back(tmp % 10);
carry = tmp / 10;
k /= 10;
}
if (carry) {
res.emplace_back(carry);
}
reverse(res.begin(), res.end());
return res;
}
};
复杂度分析
令 n 为数组长度。
将对应元素从个位起往前依次相加,当有进位时,需要考虑进位,这里我为了方便使用了链表的数据结构,把数组num和k都放到了两个链表上,依次遍历两个链表,并把结果存在一个新的链表上
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
LinkedList<Integer> list1 = new LinkedList<>();
LinkedList<Integer> list2 = new LinkedList<>();
LinkedList<Integer> list3 = new LinkedList<>();
for (int i : num) {
list1.addLast(i);
}
while (k != 0) {
list2.addFirst(k % 10);
k /= 10;
}
int carried = 0;
while (list1.size()!=0||list2.size() != 0 || carried != 0) {
int n1 = list1.size() != 0 ? list1.removeLast() : 0;
int n2 = list2.size() != 0 ? list2.removeLast() : 0;
int sum = n1 + n2 + carried;
int inser = sum % 10;
carried = sum / 10;
list3.addFirst(inser);
}
return list3;
}
}
通过int转换实现
Python3 Code:
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
#字符串与int的转换
resStr = ""
for i in num:
resStr +=str(i)
res = str(int(resStr)+k)
reslist = []
for i in res:
reslist.append(int(i))
return reslist
if __name__ == '__main__':
A = [1,2,0,0]
K = 34
ret = Solution().addToArrayForm(A, K)
print(ret)
复杂度分析
令 n 为数组长度。
public List<Integer> addToArrayForm(int[] num, int k) {
int[] numK = intToArray(k);
int a = num.length - 1;
int b = numK.length - 1;
boolean isUp = false;
Stack<Integer> stack = new Stack();
List<Integer> list = new LinkedList();
while(a>=0 || b>=0 || isUp){
int result = 0;
if(isUp){
result = 1;
isUp = false;
}
if(a <0 && b<0){
//result += 0;
}else if(a <0){
result += numK[b];
}else if(b <0){
result += num[a];
}else{
result += num[a] + numK[b];
}
a--;
b--;
if(result >= 10){
isUp = true;
}
stack.push(result % 10);
System.out.print("stack: [");
System.out.print( result % 10);
System.out.print("]");
}
while(!stack.isEmpty()){
list.add(stack.pop());
}
return list;
}
public int[] intToArray(int k) {
System.out.print("intToArray: [");
String temp = String.valueOf(k);
int[] result = new int[temp.length()];
for(int i=0; i<temp.length(); i++){
result[i] = Integer.parseInt(String.valueOf(temp.charAt(i)));
System.out.print(result[i]);
}
System.out.print("]");
return result;
}
O(3n) O(2n)
class Solution {
public:
vector
因为js在大数计算时有精度问题,因此把每一位单独计算
把k转化成数组方便计数
在这里为了方便所以把数组反转了
考虑首位可能会出现进位问题再单独处理下
var addToArrayForm = function(num, k) {
let over = false;
let kArr = k.toString().split('');
let index = 0;
let newArr = [];
num.reverse();
kArr.reverse();
while (index < num.length || index < kArr.length) {
let i = num[index] || 0
let k = Number(kArr[index]) || 0
let res = i + k
if (index > 0 && over) {
res += 1
}
if (res >= 10) {
over = true;
newArr.push(res - 10)
} else {
over = false;
newArr.push(res)
}
index ++
}
if (over) newArr.push(1);
return newArr.reverse()
};
时间复杂度: o(n)
逐位相加的思路,记录进位数。遍历完k和数组,遍历过程中,数组超出范围时,以0代替当次累加。遍历完毕后,如果存在进位,则将进位数增加到首部。
/**
* @param {number[]} num
* @param {number} k
* @return {number[]}
*/
var addToArrayForm = function(num, k) {
let i = num.length - 1, carry = 0,res = [];
while (i >= 0 || k > 0) {
let sum = ( i < 0 ? 0 : num[i] ) + k%10 + carry;
if (sum >= 10) {
carry = 1;
sum = sum % 10;
} else {
carry = 0
}
res.push(sum)
i--;
k = parseInt(k/10)
}
if (carry === 1) {
res.push(carry)
}
return res.reverse();
};
时间复杂度:O(MAX(M,N)) M 数组长度,N k长度
空间复杂度:O(MAX(M,N)) M 数组长度,N k长度
1、逐位相加法,逐位数字相加在一起,遇到相加等于 10 的时候要进位,把进位的 1 加入到下一位计算中
2、将整个加数 k 加数加入数组表示数的最低位(简单点)
JavaScript Code:
/**
* @param {number[]} num
* @param {number} k
* @return {number[]}
*/
var addToArrayForm = function (n, k) {
var res = [];
for (var i = n.length - 1; i >= 0; --i) {
var sum = n[i] + (k % 10);
k = Math.floor(k / 10);
// 如果相加大于10,则进位,把进位的1加入到下一位计算中
if (sum >= 10) {
k++;
sum = sum % 10;
}
res.push(sum);
}
// 如果n>num的长度
for (; k > 0; k = Math.floor(k / 10)) {
res.push(k % 10);
}
return res.reverse();
};
/**
* @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;
};
复杂度分析
令 n 为数组长度。
public static List<Integer> addToArrayForm(int[] num, int k) {
Stack<Integer> result = new Stack<>();
List<Integer> finalResult = new ArrayList<>();
int l = num.length;
boolean carry = false;
while (l != 0 || k != 0){
int a = 0, b = k % 10;
if(l != 0) a = num[--l];
k /= 10;
int c = a + b;
if(carry) {
c += 1;
carry = false;
}
if(c >= 10) carry = true;
result.push(c % 10);
}
if (carry) result.push(1);
while (!result.empty()) finalResult.add(result.pop());
return result;
}
先在对应位置一一相加,再进行进位操作
Javascript code:
var addToArrayForm = function(num, k) {
let temp = 0;
const kLen = k.toString().length;
for (let i = 0;i < kLen;i++) {
if (num.length < kLen) num.unshift(0);
temp = k % 10;
k = Math.floor(k / 10);
num[num.length - 1 - i] += temp;
}
const nLen = num.length;
for (let i = nLen - 1;i > 0;i--) {
if (num[i] >= 10) {
num[i - 1] += 1
num[i] = num[i] % 10;
}
}
if (num[0] >= 10) {
num[0] = num[0] % 10;
num.unshift(1);
}
return num;
};
时间复杂度O(max(N,logk))
空间复杂度O(1)
思路: A 的当前位 + B 的当前位 + 进位, 最后判断是否还有进位
class Solution {
public List<Integer> addToArrayForm(int[] A, int K) {
int n = A.length;
List<Integer> res = new ArrayList<>();
int i = n - 1, sum = 0, carry = 0;
while (i >= 0 || K != 0) {
int x = i >= 0 ? A[i]: 0;
int y = K != 0 ? K % 10 : 0;
sum = x + y + carry;
carry = sum / 10;
K = K / 10;
i--;
res.add(0, sum % 10);
}
if (carry != 0) res.add(0, carry);
return res;
}
}
遍历数组A,取出每个元素转换为字符串,再拼在一起,然后转为int整形,再与整数K相加,得出的结果再转为字符串,再遍历每一个元素输出到新的数组中。
def fun(A,K):
a=''.join(str(x) for x in A)
b=int(a)+K
out=[]
for i in str(b):
out.append(int(i))
print(out)
A = [1,2,0,0]
K = 34
fun(A,K) #[1, 2, 3, 4]
fun(A = [2,7,4], K = 181) #[4, 5, 5]
fun(A = [2,1,5], K = 806) #[1, 0, 2, 1]
fun(A = [9,9,9,9,9,9,9,9,9,9], K = 1) #[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
时间复杂度: O(n),n为数组A的长度。
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List <Integer> arr = new ArrayList <Integer>();
for(int i=num.length-1;i>=0;i--){
int p=k%10;
k=k/10;
int sum = num[i]+p;
if(sum>=10){
k+=1;
sum-=10;
}
arr.add(sum);
}
for(;k>0;k=k/10){
int s= k%10;
arr.add(s);
}
Collections.reverse(arr);
return arr;
}
}
按位相加,长度先以已知数组为标准处理
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
int i = 0;
int sum = 0;
vector<int> res;
if(k == 0)return num;
for(i = num.size()-1;(i>=0);--i)
{
sum = num[i] + k%10;
k = k/10;
if(sum >= 10 ){
k = k + 1;
sum = sum - 10;
}
res.push_back(sum);
}
for(;k>0;k = k/10) {
res.push_back(k%10);
}
reverse(res.begin(),res.end());
return res;
}
};
复杂度分析
如果直接在数组A上做加法和进位,如果和的长度大于A,需要在A前面插入元素,在数组中不太好实现,所以还是要用新的数组来存放。 python
class Solution{
def AddListAndInt(int[] A, int K):
n = len(A)
sum = A[0]
for i in range(1, n):
sum = sum*10 + A[i]
sum = sum + K
tem = []
while(sum > 0):
item = sum%10
tem.append(item)
sum = sum//10
return tem[::-1]
}
class Solution:
def addToArrayForm(self, num: List[int], k: int) -> List[int]:
n = 0
for i in num:
n = n * 10 + i
n += k
return [int(ch) for ch in str(n)]
从n-1至0开始遍历A数组,将其与K对应位置上的进行累加(通过取余获取K各个位置上的值,K%10,(int)(k/10)),如大于等于10则需进位+1,flag为进位标志。 当K位数大于A数组长度时,需将K的剩余位置的值也添加至结果集合中,同时也需要判断进位。 最后当A数据与K全部遍历完毕后,如还有进位,则需于结果集合中再度添加1。
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> list = new ArrayList<Integer>();
boolean flag = false; // 判断是否需要进位+1
for (int i = num.length-1; i >=0 ; i--) {
if(k==0){
int curValue = flag ? num[i]+1:num[i];
flag = curValue>=10;
list.add(flag?curValue-10:curValue);//进位则加1
}else {
int n = k % 10;//k最后一位
int curValue = flag ? num[i]+n+1:num[i]+n;
flag = curValue>=10;
list.add(flag ?curValue-10:curValue);
k /= 10;
}
}
while (k!=0){//num数组已累加完毕,k未累加完毕
int n = k%10;//k最后一位
int curValue = flag ? n+1:n;
flag = curValue>=10;
list.add(flag?curValue-10:curValue);
k/=10;
}
//k已累加完毕,仍然需要进位,则结果list add 1(如9+1=10这种情况)
if(k==0&&flag){
list.add(1);
}
Collections.reverse(list);
return list;
}
复杂度分析
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