数据结构与算法之深入解析“字符串相加”的求解思路与算法示例

Posted Serendipity·y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法之深入解析“字符串相加”的求解思路与算法示例相关的知识,希望对你有一定的参考价值。

一、题目要求

  • 给定两个字符串形式的非负整数 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 都不包含任何前导零。

二、求解算法

① 模拟

  • 本题只需要对两个大整数模拟「竖式加法」的过程,竖式加法就是平常学习生活中常用的对两个整数相加的方法,回想一下在纸上对两个整数相加的操作,是不是如下图将相同数位对齐,从低到高逐位相加,如果当前位和超过 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;
    
;
  • 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();
    

② 双指针

  • 设定 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();
    

  • 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

以上是关于数据结构与算法之深入解析“字符串相加”的求解思路与算法示例的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之深入解析“股票的最大利润”的求解思路与算法示例

数据结构与算法之深入解析“安装栅栏”的求解思路与算法示例

数据结构与算法之深入解析“最长连续序列”的求解思路与算法示例

数据结构与算法之深入解析“路径总和”的求解思路与算法示例

数据结构与算法之深入解析“斐波那契数”的求解思路与算法示例

数据结构与算法之深入解析“连续整数求和”的求解思路与算法示例