算法 - 字符串相加(大数相加)
1. 题目
给定两个用字符串表示的非负整数 num1 和 num2,计算它们之和,并用字符串形式返回。
要求:不能直接使用任何内置的大整数库,也不能把整个输入字符串直接转换成整数(会溢出)。
示例:
1 | 输入: num1 = "11", num2 = "123" |
2. 解题思路
模拟小学竖式加法,从**个位(字符串末尾)**开始逐位相加并处理进位。
2.1 双指针从尾部向前
i、j分别指向num1、num2的末尾,carry为进位。每一步:取当前位数字(指针越界则视为 0),
sum = d1 + d2 + carry。当前结果位 =
sum % 10,新的carry = Math.floor(sum / 10)。结果字符往前拼接(或 push 后反转)。
循环条件:
i >= 0 || j >= 0 || carry——最后的 carry 不能漏。时间复杂度:O(max(m, n)),空间复杂度:O(max(m, n))(结果串)。
3. TypeScript 实现
3.1 标准双指针
1 | function addStrings(num1: string, num2: string): string { |
3.2 变体:字符串相乘(大数乘法)
同族题,用 i + j、i + j + 1 定位乘积位在结果数组中的落点,双循环累加后再统一处理进位。面试常作为追问。
4. 面试延伸
- 为何用 charCodeAt 而非 parseInt:逐字符
+ '0'或charCodeAt - 48更快,且体现「不整体转 int」的约束。 - JS 的坑:
Number只有 53 位安全整数(Number.MAX_SAFE_INTEGER),超大数相加若直接+会丢精度——这正是本题要求模拟竖式的现实动机;实际项目大数运算常用BigInt。 - 相关:链表版本「两数相加」(LeetCode 2),用链表节点从低位到高位模拟同样的进位逻辑。
- 结果拼接用数组 push + 反转,避免字符串反复
+=头部的 O(n²) 开销。
难度:简单 | LeetCode 415 | 字符串/模拟