给定两个字符串形式的非负整数 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 <= 104
num1
和num2
都只包含数字0-9
num1
和num2
都不包含任何前导零
1、模拟
题目不让使用int转型,也不让用类似于java中BigInteger这种来处理大数,故这里使用模拟思路,相比大家学小学数学都用过竖式加法,这里可以用一样的思路
- 两数对齐,即把字符串的长度搞成一样的,具体就是谁短一点,把这个字符串前面补若干个“0”
- 设置进位变量,考虑到做加法的时候可能会有进位的情况,可以把初始化进位设置为0,每一位做加法的时候加上进位量
- 全部加完后,如果进位量等于1,则需要在最后结果字符串左边加“1”
- 位数做加法时,不能用int转型,可以巧用ASCII值处理,即字符的ASCII值减去字符“0”的ASCII值即为加法结果
时间:O(max(len1, len2)),即遍历次数为两个字符串最大的长度
空间:O(1),若干变量
py:
class Solution:
def addStrings(self, num1: str, num2: str) -> str:
res = ""
// 长度对齐
len1, len2 = len(num1), len(num2)
length = max(len1, len2)
if length > len1:
num1 = "0" * (length - len1) + num1
if length > len2:
num2 = "0" * (length - len2) + num2
// 进位量
carry = 0
// 倒序遍历
for i in range(length - 1, -1, -1):
// 计算
n = ord(num1[i]) + ord(num2[i]) - ord("0") * 2 + carry
// 更新进位量,下一次循环使用
carry = n // 10
// 加入结果字符串
res = str(n % 10) + res
// 返回结果,如果遍历完进位量还是1就加上
return res if carry == 0 else "1" + res
java版本写的很丑,凑合看看,,
class Solution {
public String addStrings(String num1, String num2) {
// 结果
StringBuilder res = new StringBuilder();
// 取最大长度
int len1 = num1.length(), len2 = num2.length();
int len = Math.max(len1, len2);
// 对齐字符串,这里用了两个sb....
if (len > len1) {
StringBuilder sb1 = new StringBuilder(num1);
for (int i = 0; i < len - len1; i++) {
sb1.insert(0, "0");
}
num1 = sb1.toString();
}
if (len > len2) {
StringBuilder sb2 = new StringBuilder(num2);
for (int i = 0; i < len - len2; i++) {
sb2.insert(0, "0");
}
num2 = sb2.toString();
}
// 进位值
int carry = 0;
for (int i = len - 1; i >= 0; i--) {
// 加法
int n = num1.charAt(i) + num2.charAt(i) - '0' - '0' + carry;
// 更新进位值
carry = n / 10;
// 把个位数字加入结果
res.insert(0, String.valueOf(n % 10));
}
// 最后判断carry
if (carry == 1) {
res.insert(0, "1");
}
return res.toString();
}
}