PS:算法并非原创,仅作个人学习记录使用,侵删
题目描述
算法分析
本人初步的思路是:先把数组转化为整数,然后进行加法运算,之后将加法结果不断除10取余转化为数组。这也是本篇中的python解法。
但是在文章末尾,可以看到这种做法运行耗时非常大,原因在于测试数据里面有较大的整数相加,当出现这种情况时,python那种解法就不是很理想了。
所以本题使用了整数相加的相关法则,一种方式是将K转为数组,之后进行诸位相加和进位;另一种是K和A的每位进行相加,并截去个位。
但是我总觉得这种方式和计算机内部的二进制加法器相当类似。
代码实现
【C】
/*
逆序遍历A中每个数,每个数都和K相加,保留个位,K截去个位继续操作,最终得出结果。
这样不需要将K转换为整数数组
*/
int* addToArrayForm(int* A, int ASize, int K, int* returnSize){
//1.判断临界条件
if(A==NULL||K==0)
{
*returnSize=ASize;
return A;
}
//2.计算待返回数组大小,及为数组开辟空间。(整数的位数=log10(x)+1)
//由于他们和有可能最高位出现进位的情况,所以多开辟一位数的大小。
int ksize=log10(K) + 1;//计算K的位数
*returnSize = ASize>ksize?ASize+1:ksize+1;//考虑进位,+1
int *retArr=(int *)malloc(sizeof(int)*(*returnSize));//分配内存空间
//3.逆序遍历数组,并对每一个值进行+k操作,将得到的数取最后一位,并将最后一位数赋值给新数组后面未赋值的一位。如:A=[1,2,3,1],K=35,第一次操作为1+35=36,将最后一位6放到新数组后面未赋值的一位。
//两种情况:①K比A位数长;②A比K位数长;
int retend=*returnSize;
while(K>0 || retend-1>0){//逆序遍历数组
if(ASize>0)
K+=A[--ASize];
retArr[--retend]=K%10;
K/=10;
}
*returnSize-=retend;
return retArr+retend;
}
【C++】
/*
A和K个位逐个相加,如果结果大于9则进1
*/
class Solution {
public:
vector<int> addToArrayForm(vector<int> &A, int K) {
vector<int> res;//最终的结果数组
int n = A.size();
for (int i = n - 1; i >= 0; --i) {
int sum = A[i] + K % 10;//A和K个位相加
K /= 10;//K截去个位
if (sum >= 10) {//如果个位相加的值大于10,那么K当前个位(原K的十位+1.相加结果sum-10控制个位范围
K++;
sum -= 10;
}
res.push_back(sum);//sum是每个个位相加的最终结果
}
for (; K > 0; K /= 10) {//如果K比A长的情况
res.push_back(K % 10);
}
reverse(res.begin(), res.end());//由于push_back是从列表开头进行操作的,所以需要反转
return res;
}
};
【Java】
/*
逆序遍历A中每个数,每个数都和K相加,保留个位,K截去个位继续操作,最终得出结果。
这样不需要将K转换为整数数组
*/
class Solution {
public List<Integer> addToArrayForm(int[] A, int K) {
List<Integer> res = new ArrayList<Integer>();
int n = A.length;
for (int i = n - 1; i >= 0 || K > 0; --i, K /= 10) {//K每次截取个位
if (i >= 0) {
K += A[i];
}
res.add(K % 10);//得到K的个位
}
Collections.reverse(res);
return res;
}
}
【python】
#将A数组转为整数,得出相加结果再转为数组
class Solution:
def addToArrayForm(self, A, K):
n = len(A)
a=0
for i in range(n):
a = a + A[i]*(10**(n-i-1))
return str(a+K)
python参考网址
但是python的这种解法,耗时很大