0415.字符串相加
难度:🟢 简单
标签:数学
、字符串
、模拟
、双指针
链接:415. 字符串相加
题目描述
给定两个字符串形式的非负整数 num1
和 num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123"
输出:"134"
示例 2:
输入:num1 = "456", num2 = "77"
输出:"533"
示例 3:
输入:num1 = "0", num2 = "0"
输出:"0"
提示:
1 <= num1.length, num2.length <= 10^4
num1
和num2
都只包含数字0-9
num1
和num2
都不包含任何前导零
解题思路
核心思想
本题的核心思想是 模拟我们小学时学过的竖式加法。我们从两个数字的最低位(即字符串的末尾)开始,逐位相加,并处理好每一位的进位,直到两个数的所有位都被处理完毕。
思路选择
由于题目禁止直接将字符串转为整数(会超出数字类型的表示范围),我们必须逐位进行操作。双指针 是实现这一目标的理想方法。我们可以初始化两个指针,分别指向两个字符串的末尾,然后同步向左移动,模拟从个位、十位、百位……依次相加的过程。
关键步骤
初始化:创建两个指针
i
和j
,分别指向num1
和num2
的最后一个字符。初始化进位carry = 0
。创建一个空数组result
用于存放计算结果的每一位。循环计算:当
i
或j
仍在有效范围内,或者最后仍有进位carry > 0
时,持续循环。取值:在循环内部,获取
num1[i]
和num2[j]
对应的数字。如果某个指针已经越界(例如i < 0
),则其对应的位视为0
。一个将字符转换为数字的小技巧是char - '0'
。求和:计算当前位的和
sum = digit1 + digit2 + carry
。处理结果与进位:
当前位应存入的结果是
sum % 10
。新的进位是
Math.floor(sum / 10)
。
结果拼接:将计算出的当前位结果存入
result
数组。返回:循环结束后,
result
数组中是倒序的结果(例如134
在数组中是[4, 3, 1]
)。将其反转(reverse()
)后再合并成字符串(join('')
)即可得到最终答案。
代码实现
/**
* @param {string} num1
* @param {string} num2
* @return {string}
*/
var addStrings = function (num1, num2) {
let i = num1.length - 1;
let j = num2.length - 1;
let carry = 0;
const result = []; // 使用数组存储结果,比字符串拼接更高效
// 循环条件:只要还有位未处理,或者最后还有进位,就继续
while (i >= 0 || j >= 0 || carry > 0) {
// 如果指针有效,则取其值,否则视为0
const digit1 = i >= 0 ? num1.charAt(i) - '0' : 0;
const digit2 = j >= 0 ? num2.charAt(j) - '0' : 0;
const sum = digit1 + digit2 + carry;
// 当前位的结果是和的个位数
result.push(sum % 10);
// 新的进位是和的十位数
carry = Math.floor(sum / 10);
// 移动指针
i--;
j--;
}
// 将结果数组反转并拼接成字符串
return result.reverse().join('');
};
复杂度分析
时间复杂度:O(max(N, M)) 其中 N 和 M 分别是
num1
和num2
的长度。我们需要遍历完两个字符串中较长的那一个。空间复杂度:O(max(N, M)) 我们使用了一个数组来存储结果,其长度与较长的输入字符串相当。因此空间复杂度与输入规模成正比。(注:若不考虑存储输出结果所占用的空间,则为 O(1))。
相关题目
0002.两数相加:本题的链表版本,思路完全相同。
0043.字符串相乘:模拟竖式乘法,是本题的进阶版。
0067.二进制求和:将十进制加法改为二进制加法,逻辑类似。
总结
本题是一道非常经典的模拟题,旨在考察对基本计算过程的编程实现能力。双指针法是解决此类问题的通用且高效的模式。代码实现的关键在于处理好边界条件(如两个字符串长度不同)以及循环结束时可能存在的最后一次进位。使用数组 result.push()
后再 reverse().join('')
的方式是 JavaScript 中处理循环内字符串拼接的一个推荐实践。