题目来源:力扣415.字符串相加(本文章用C++进行解题)(主要还是思路分享)
题意:
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger
), 也不能直接将输入的字符串转换为整数形式。
解析:
本题是一个科学大数问题:用string库中的stoll函数(字符串转数字),to_string(数字转字符串)行不通的(断绝捷径)
class Solution {
public:
string addStrings(string num1, string num2) {
long long x=stoll(num1);
long long y=stoll(num2);
long long z=x+y;
return to_string(z);
}
};
我们将小学的加法拿起来用下:“456”+“77”
从低位开始取数(个位开始) 1 and 7
int end1=num1.size()-1;
int end2=num2.size()-1;
6+7=13 ----- 进位是1
5+7+(进位)1=13 ----- 进位是1
4+0+(进位)1=5 ----- 进位是0
短的结束还不能真的结束,长的结束才算是结束(有一个>0就结束)
while(end1>=0||end2>=0)
简单的个位数转换(字符->数字)
num1[end1]-'0'
next表示进位
int next = 0;
加法实现:
while(end1>=0||end2>=0)
{
int val1=(end1>=0 ? num1[end1--]-'0' : 0);
int val1=(end2>=0 ? num2[end2--]-'0' : 0);
int ret=val1+val2+next;
next=ret/10;
ret=ret%10;
}
给个字符串来存末尾
string str;
1.用头插:(insert):(接口)
用迭代器的方式:
str.insert(str.begin(),'0'+ret);
注意:如果num1="1" num2="9" 的话(这种个位+个位有进位的),会有一个进位的丢失
所以:
if(next==1)
{
str.insert(str.begin(),'1');
}
2.用尾插:(+= 或 push_back)(在string重载了一个+=:(尾插))
因为在一次的头插就有时间复杂度O(N)了,头插N个,构成等差数列,时间复杂度是O(N^2)
那么尾插整体的时间复杂度就只有O(N) ,尾插造成数据的逆序,再用SLT的逆置:reverse
str+=('0'+ret);
if(next==1)
{
str+='1';
}
reverse(str.begin(),str.end());
answer:
头插:
class Solution {
public:
string addStrings(string num1, string num2) {
string str;
int end1=num1.size()-1;
int end2=num2.size()-1;
int next=0;
while(end1>=0||end2>=0)
{
int val1=(end1>=0 ? num1[end1--]-'0' : 0);
int val2=(end2>=0 ? num2[end2--]-'0' : 0);
int ret=val1+val2+next;
next=ret/10;
ret=ret%10;
str.insert(str.begin(),'0'+ret);
}
if(next==1)
{
str.insert(str.begin(),'1');
}
return str;
}
};
尾插:
class Solution {
public:
string addStrings(string num1, string num2) {
string str;
int end1=num1.size()-1;
int end2=num2.size()-1;
int next=0;
while(end1>=0||end2>=0)
{
int val1=(end1>=0 ? num1[end1--]-'0' : 0);
int val2=(end2>=0 ? num2[end2--]-'0' : 0);
int ret=val1+val2+next;
next=ret/10;
ret=ret%10;
str+=('0'+ret);
}
if(next==1)
{
str+='1';
}
reverse(str.begin(),str.end());
return str;
}
};