43.字符串相乘
2020-04-16
字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,
返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
题解:
竖式乘法
首先需要知道一点:两个数字相乘,最后的结果的长度必然小于两者的长度之和。
竖式乘法就是采用的这种思想,相当于将结果整个采用数组的方式存储。如图:
图中结果数组中的第 k 位在哪些情况下会被修改呢?
现在我们假设 num1 当前的位置是 i ,num2 当前的位置是 j 。
那么可以看出:i + j + 1 == k 时第 k 位会被直接修改,同时也可能会进位第 k - 1 位。
具体情况如下:
- 结果的 第 k 位 上的值就是(原来第 k 位的值 ret[k] + 增量 num1[i] * num2[j] )之和的余数。
- 结果的 第 k - 1 位,可能会得到 ret[k] + num1[i] * num2[j] 运算产生的进位。
/** * @param {string} num1 * @param {string} num2 * @return {string} */ var multiply = function (num1, num2) { if (num1 === '0' || num2 === '0') return '0'; // 两数相乘 结果最多位数为两个数的长度之和 res作为总结果的数组 最后一位是个位的值 倒数第二是十位 以此类推 let res = new Array(num1.length + num2.length).fill(0); // 从两个字符串的最后一位开始计算 最后一位计算的值可以确定 总结果 的个位的值 并且有可能进一位个十位 for (let i = num1.length - 1; i >= 0; i--) { // 遍历字符串1 let n1 = num1.charAt(i) - '0'; // 得到下标为i时的数值 for (let j = num2.length - 1; j >= 0; j--) { // 遍历字符串2 let n2 = num2.charAt(j) - '0'; // 得到下标为j时的数值 const sum = (res[i + j + 1] + n1 * n2); // 和为结果数组[i+j+1]项的值 + n1 * n2 res[i + j + 1] = sum % 10; // 和取余数得到当前位的值 res[i + j] += Math.floor(sum / 10); // 结果取整数为进一位的值 } } for (let i = 0; i < res.length; i++) { // 去掉开头可能出现的0 if (res[i] !== 0) { res = res.slice(i); return res.join(''); } } };