23. 大数相加问题【LC】

162 阅读1分钟

题目:

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

核心思路:

大数运算的核心思路是模拟算式运算。 即,模拟算式运算,按位处理的方式。以本题加法为例,详细解释一下:

我们需要准备一个进数位temp,来记录每个当前位求和后的进数。加完后将当前位的处理结果从头向后插入一个list中。

另外,我们需要一个变量来控制加法运算有效位数。

形式上基本上如下:

//模拟算式运算
//      1 6 3  【1】
// +  2 3 7 5  【2】
// -----------
//      1      【3】
// -----------
//    2 4 3 8

每一位运算都是在做以下处理:

当前位总和:res[x] = num1[x] + num2[x] + temp; 进数:temp = res[x] / 10, 向下取整; 当前位保留值:res[x] = res[x] % 10

注意两点:

  • 1)控制运算位数,以两数中位数较大的为标准;
  • 2)遍历完毕后要处理一下temp,可能存在值;

解:

var addStrings = function (num1, num2) {
  const arr1 = num1.split('').reverse(); // 反转的目的是从低位往高位算
  const arr2 = num2.split('').reverse();
  let temp = 0; //运算进位
  let idx = 0; // 控制位数
  const res = [];
  while (arr1.length > idx || arr2.length > idx) { // 以两个数中,位数更大的一个为标准
    let item01 = arr1.length > idx ? arr1[idx] : 0;
    let item02 = arr2.length > idx ? arr2[idx] : 0;
    // 算术中,当前位相加并进位
    let itemRes = (+item01) + (+item02) + temp;
    temp = itemRes > 9 ? 1 : 0; // 当前位算完,进位
    // 当前位进位后,最终值
    res.unshift(itemRes % 10)
    idx++;
  }
  // 若两个以两个中最大位数都完成遍历,以及相加
  if (temp) {
    res.unshift(temp)
  }
  return res.join('')
};

———— 前端、Javascript实现、算法、刷题、leetcode