LeetCode 415. Add String 解题报告
题目描述
Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2.
- The length of both num1 and num2 is < 5100.
- Both num1 and num2 contains only digits 0-9.
- Both num1 and num2 does not contain any leading zero.
示例
“0”
“1”
return “1”
限制条件
You must not use any built-in BigInteger library or convert the inputs to integer directly.
解题思路
我的思路:
其实题目就是一个大数相加,不过限制了不能使用大数的库以及把输入的两个字符串直接转为整数。不过这没关系,题目是挺简单的。
思路就是按照平时我们列竖式做加法的过程去做。
1.我们做加法都是从加数的最后一位开始的,所以我们需要设置两个指针i和j,分别从num1和num2的最后一位开始往前扫描。
2.每一位的加法,我们至少需要将2个数相加,有三种情况:
(1)i和j没有越过数值的最高位:需要将num1[i],num2[j]和前一位的进位carray相加。
(2)i越过了num1的最高位:需要将num2[j]和前一位的进位carry相加。
(3)j越过了num2的最高位:需要将num1[i]和前一位的进位carry相加。
3.计算了当前为的和tempSum后,就要判断当前位是否要进位,如果tempSum
≥
10,carry就等于1,把tempSum - 10的结果对应的字符放到结果中,否则carry等于0,把tempSum对应的字符放到结果。
4.重复2,3步,知道i和j都越过了数值的最高位,此时我们还要判断carry是否为1,如果是我们就得在结果前补上最高位1,原因就是“1” + “9” = “10”。最后返回结果即可。
参考思路:
做这道题的思路核心部分就是我上面的过程。然而同样的思路,每个人写出来的代码都不一样,有大神就写出了很精巧的代码。改进的地方有如下几处(用numSmall表示num1,num2较小的数,用numBig表示num1,num2较大的数):
1.使用了递归确保了i指向的是numBig
2.加法的过程简洁地归纳成carry加上numBig[j],当numSmall[j]存在(即小的数对应的位存在)加上numSmall[j]。
3.没有申请额外的空间,直接把结果复写到numBig中。
4.对于长度不一的两个加法时,能够提前结束,比如“100000009” + “1”在做完十位的加法后就能结束,而不用一直扫描“100000009”的其他位。结束的条件是,j越过了numSmall的最高位并且进位0;
代码
我的代码
class Solution {
public:
string addStrings(string num1, string num2) {
string sum = "";
int i = num1.size() -1;
int j = num2.size() -1;
int tempSum = 0;
int carryBit = 0;
char* n[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
while (i >= 0 || j >= 0) {
if (j < 0)
tempSum = (num1[i--] - '0') + carryBit;
else if (i < 0)
tempSum = (num2[j--] - '0') + carryBit;
else
tempSum = (num1[i--] - '0') + (num2[j--] - '0') + carryBit;
if (tempSum >= 10) {
carryBit = 1;
sum = n[tempSum - 10] + sum;
} else {
carryBit = 0;
sum = n[tempSum] + sum;
}
}
return carryBit? "1" + sum: sum;
}
};
参考代码:
class Solution {
public:
string addStrings(string num1, string num2) {
int i = num1.size() - 1, j = num2.size() - 1, carry = 0;
if (i < j)
return addStrings(num2, num1);
for(;(j >= 0 || carry) && i >= 0; carry /= 10) {
if(j >= 0)
carry += num2[j--] - '0';
carry += num1[i] - '0';
num1[i--] = carry % 10 + '0';
}
return carry? "1" + num1: num1;
}
};
总结
这道题不算很难,关键的地方是能够清楚利用字符串做加法时是按照每一位来做的以及每一位的加法都有哪些数参加。弄清这两个地方那基本的程序框架就能出来,还有一个比较小的需要注意的地方是计算出来的整型结果转成字符串, 我的方式是使用了一个额外的字符串数组,当然用to_string也是可以的。大神的代码真的好厉害,又学到了好多东西,尤其是那一招递归的使用,这技能get it~
其实这是昨晚填的坑,今天争取填一个新的坑,加油加油!