LeetCode 415:字符串相加

181 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

LeetCode 415:字符串相加

题目描述:

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例1

输入: num1 = "11", num2 = "123"
输出: "134"

示例2

输入: num1 = "456", num2 = "77"
输出: "533"

示例3

输入: num1 = "0", num2 = "0"
输出: "0"

解题思路 

思路一: 模拟「竖式加法」的过程

定义两个指针 i 和 j 分别指向 num 1和num2的末尾,即最低位,同时定义一个变量 add 维护当前是否有进位,然后从末尾到开头逐位相加即可。
那如果两个数字位数不同怎么处理呢?

我们统一在指针当前下标处于负数的时候返回 0,等价于对位数较短的数字进行了补零操作,这样就可以除去两个数字位数不同情况的处理。

  1. 计算进位: 计算 add = result / 10,代表当前位相加是否产生进位;
  2. 添加当前位: 计算 result = n1 + n2 + add,并将当前位 result % 10 添加至 ans 头部;
  3. 索引溢出处理: 当指针 i或j 走过数字首部后,给 n1,n2 赋值为 0,相当于给 num1,num2 中长度较短的数字前面填 0,以便后续计算。

实现代码如下:

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var addStrings = function (num1, num2) {
  let i = num1.length - 1,
    j = num2.length - 1,
    add = 0;  // 表示进位
  const ans = [];
  while (i >= 0 || j >= 0 || add != 0) {
    const x = i >= 0 ? num1[i] - "0" : 0;
    const y = j >= 0 ? num2[j] - "0" : 0;  // 转成数字
    const result = x + y + add;
    ans.push(result % 10);
    add = Math.floor(result / 10);
    i -= 1;
    j -= 1;
  }
  return ans.reverse().join("");
};

时间复杂度: O(max(len1,len2)) , 竖式加法的次数取决于较大数的位数

空间复杂度: O(n)

不使用数组

var addStrings = function (num1, num2) {
  let i = num1.length,
    j = num2.length,
    result = '', 
    add = 0;  // 表示进位
  while (i || j) {
    i ? add += +num1[--i]: '';
    j ? add += +num2[--j]: '';

    result = add % 10 + result;
    if (add > 9) add = 1
    else add = 0
  }
  if(add) result = 1 + result;
  return result
};

参考资料

LeetCode 415.字符串相加 - 力扣(LeetCode)