
🚀 你好,欢迎来到《编程闯关记》! 这里是算法与数据结构的实战基地,也是你从“暴力解法”到“最优解”的进化场。
🔍 专栏初衷:
💡 如何使用本专栏: 1️⃣ 先独立思考:尝试自己写出第一版代码(哪怕很烂)。 2️⃣ 对比解法:看看我的思路和你的差异,吸收优化技巧。 3️⃣ 举一反三:每篇末尾会附相似题目链接,趁热打铁。
📌 坚持打卡: 算法没有捷径,但正确的方法能让你少走弯路。每天15分钟,和我一起用代码雕刻思维!
给定两个字符串形式的非负整数 num1 和 num2,计算它们的和并同样以字符串形式返回。
你不能使用任何内建的大数类型(比如 BigInteger)或直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123"
输出:"134"示例 2:
输入:num1 = "456", num2 = "77"
输出:"533"示例 3:
输入:num1 = "0", num2 = "0"
输出:"0"这道题要求我们实现两个字符串形式的数字相加,并返回字符串结果。由于输入的数字可能非常大,超出常规整数类型的范围,所以不能直接转换为整数进行计算。
这个问题本质上是在模拟我们小学学习的竖式加法运算过程:
我们可以采用以下步骤解决这个问题:
class Solution {
public:
string addStrings(string num1, string num2) {
string str;
str.reserve(max(num1.size(),num2.size())+1);
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int carry = 0;
while(end1 >= 0 || end2 >= 0)
{
int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;
int val = x1 + x2 + carry;
carry = val / 10;
val = val % 10;
str +=('0' + val);
}
if(carry ==1 )
{
str += '1' ;
}
reverse(str.begin(),str.end());
return str;
}
};初始化:
string str;
str.reserve(max(num1.size(),num2.size())+1);我们预先为结果字符串分配足够的空间,最大长度为两个输入字符串中较长的那个加1(可能的进位)。
设置指针和进位:
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int carry = 0;end1和end2分别指向两个字符串的末尾(最低位),carry用于记录进位。
逐位相加:
while(end1 >= 0 || end2 >= 0)
{
int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;
int val = x1 + x2 + carry;
carry = val / 10;
val = val % 10;
str +=('0' + val);
}num[i] - '0'处理最终进位:
if(carry == 1)
{
str += '1';
}如果最后还有进位,需要在结果中添加一个’1’。
反转结果:
reverse(str.begin(),str.end());因为我们是从低位到高位构建结果的,所以最后需要反转字符串。
reserve()预分配内存,避免多次内存重新分配,提高效率。+=运算符追加字符,简化了代码。这道题是一个经典的大数加法问题,通过模拟人工计算的过程,我们可以实现任意长度的数字相加。关键点在于:
这种方法不仅可以用于解决本题,还可以扩展到其他需要处理大数运算的场景,如大数减法、乘法等。