题目
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
提示:
1 <= num1.length, num2.length <= 200
num1 和 num2 只能由数字组成。
num1 和 num2 都不包含任何前导零,除了数字0本身。
思路
基本思路是模拟乘法的过程,从乘数的最低位开始一位一位地与被乘数相乘,然后将每一位的乘积相加得到最终结果。
具体实现思路如下:
- 将字符串转换成数字数组,方便计算。因为JavaScript中的数字类型可以表示非常大的数,因此我们可以使用数字类型来进行计算。
- 从乘数的最低位开始,一位一位地与被乘数相乘。将乘积存储在一个数组中,数组的下标表示乘积对应的位数,例如,数组的第0个元素表示个位上的乘积,第1个元素表示十位上的乘积,以此类推。
- 将每一位的乘积相加得到最终结果。这里需要注意的是,位数相同的乘积可能会产生进位,因此需要将进位保存下来,加到高位上。
- 将结果数组转换成字符串形式返回。
JavaScript代码实现:
var multiply = function(num1, num2) {
if (num1 === '0' || num2 === '0') return '0'; // 特判:如果有一个字符串为0,直接返回0
const n1 = num1.length, n2 = num2.length;
const pos = new Array(n1 + n2).fill(0); // 初始化结果数组,长度为num1.length + num2.length
for (let i = n1 - 1; i >= 0; i--) { // 从乘数的最低位开始遍历
const x = +num1[i]; // 将乘数的当前位转换成数字
for (let j = n2 - 1; j >= 0; j--) { // 从被乘数的最低位开始遍历
const y = +num2[j]; // 将被乘数的当前位转换成数字
const product = x * y; // 计算当前位的乘积
const p1 = i + j, p2 = i + j + 1; // 计算当前位的结果应该存储在结果数组的哪个位置
const sum = product + pos[p2]; // 计算当前位的结果加上进位的值
pos[p1] += Math.floor(sum / 10); // 更新进位
pos[p2] = sum % 10; // 更新当前位的结果
}
}
let res = '';
for (const p of pos) { // 将结果数组转换成字符串形式
if (p !== 0 || res !== '') res += p; // 跳过高位的0
}
return res;
};
- 时间复杂度:,其中 和 分别是两个字符串的长度。
- 空间复杂度:,需要存储中间结果和最终结果。