【数据结构与算法】之深入解析“字符串相加”的求解思路与算法示例
【摘要】
一、题目要求
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换...
一、题目要求
- 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
- 不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
- 示例 1:
输入:num1 = "11", num2 = "123"
输出:"134"
- 1
- 2
- 示例 2:
输入:num1 = "456", num2 = "77"
输出:"533"
- 1
- 2
- 示例 3:
输入:num1 = "0", num2 = "0"
输出:"0"
- 1
- 2
- 提示:
-
- 1 <= num1.length, num2.length <= 104;
-
- num1 和num2 都只包含数字 0-9;
-
- num1 和num2 都不包含任何前导零。
二、求解算法
① 模拟
- 本题只需要对两个大整数模拟「竖式加法」的过程,竖式加法就是平常学习生活中常用的对两个整数相加的方法,回想一下在纸上对两个整数相加的操作,是不是如下图将相同数位对齐,从低到高逐位相加,如果当前位和超过 10,则向高位进一位?因此只要将这个过程用代码写出来即可。
- 具体实现也不复杂,定义两个指针 i 和 j 分别指向 num1 和 num2 的末尾,即最低位,同时定义一个变量 add 维护当前是否有进位,然后从末尾到开头逐位相加即可。你可能会想两个数字位数不同怎么处理,这里我们统一在指针当前下标处于负数的时候返回 0,等价于对位数较短的数字进行了补零操作,这样就可以除去两个数字位数不同情况的处理。
- C++ 示例:
class Solution {
public:
string addStrings(string num1, string num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
string ans = "";
while (i >= 0 || j >= 0 || add != 0) {
int x = i >= 0 ? num1[i] - '0' : 0;
int y = j >= 0 ? num2[j] - '0' : 0;
int result = x + y + add;
ans.push_back('0' + result % 10);
add = result / 10;
i -= 1;
j -= 1;
}
// 计算完以后的答案需要翻转过来
reverse(ans.begin(), ans.end());
return ans;
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- Java 示例:
class Solution {
public String addStrings(String num1, String num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
StringBuffer ans = new StringBuffer();
while (i >= 0 || j >= 0 || add != 0) {
int x = i >= 0 ? num1.charAt(i) - '0' : 0;
int y = j >= 0 ? num2.charAt(j) - '0' : 0;
int result = x + y + add;
ans.append(result % 10);
add = result / 10;
i--;
j--;
}
// 计算完以后的答案需要翻转过来
ans.reverse();
return ans.toString();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
② 双指针
- 设定 n1,n2 两指针分别指向 num1,num2 尾部,模拟人工加法;
-
- 计算进位: 计算 carry = tmp // 10,代表当前位相加是否产生进位;
-
- 添加当前位: 计算 tmp = n1 + n2 + carry,并将当前位 tmp % 10 添加至 res 头部;
-
- 索引溢出处理: 当指针 n1 或 n2 走过数字首部后,给 n1,n2 赋值为 0,相当于给 num1,num2 中长度较短的数字前面填 0,以便后续计算。
-
- 当遍历完 num1,num2 后跳出循环,并根据 carry 值决定是否在头部添加进位 1,最终返回 res 即可。
- 初始状态:
- n1,n2 两指针分别指向 num1,num2 尾部:
- n1,n2 两指针继续分别指向 num1,num2 的十位:
- 以此类推,直到最高位:
- 最后得出结果:
- Java 示例:
class Solution {
public String addStrings(String num1, String num2) {
StringBuilder res = new StringBuilder("");
int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
while(i >= 0 || j >= 0){
int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
int tmp = n1 + n2 + carry;
carry = tmp / 10;
res.append(tmp % 10);
i--; j--;
}
if(carry == 1) res.append(1);
return res.reverse().toString();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- Python 示例:
class Solution:
def addStrings(self, num1: str, num2: str) -> str:
res = ""
i, j, carry = len(num1) - 1, len(num2) - 1, 0
while i >= 0 or j >= 0:
n1 = int(num1[i]) if i >= 0 else 0
n2 = int(num2[j]) if j >= 0 else 0
tmp = n1 + n2 + carry
carry = tmp // 10
res = str(tmp % 10) + res
i, j = i - 1, j - 1
return "1" + res if carry else res
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
文章来源: blog.csdn.net,作者:Serendipity·y,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/Forever_wj/article/details/122782907
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)