「前端刷题」43. 字符串相乘

206 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = "2", num2 = "3" 输出: "6"

示例 2:

输入: num1 = "123", num2 = "456" 输出: "56088"

说明:

  1. num1 和 num2 的长度小于110。
  2. num1 和 num2 只包含数字 0-9
  3. num1 和 num2 均不以零开头,除非是数字 0 本身。
  4. 不能使用任何标准库的大数类型(比如 BigInteger)直接将输入转换为整数来处理

思路

解题思路1 ==> 数学思路

如12 * 34:12 * 34=2 * 4 + 10 * 4 + 2 * 30 + 10 * 30
image.png==>image.png==>image.png==>image.png

  1. 设置数组res=[]来存储数据,2 * 4的时候,res["8"]
  2. 1 * 4 ==> res["8","4"]
  3. 3 * 2 = 6 + 4 =10; 因为6 + 4 >=10,那么进一位,res["8","0","1"]
  4. 3 * 1 = 3 + 进位的1 = 4 小于10,res["8","0","4"]
  5. res取反,res.reverse()==["4","0","8"]

image.png

代码

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var multiply = function(num1, num2) {
    if(num1==0 || num2==0) return "0"
    const res=[];// 结果集
    for(let i=0;i<num1.length;i++){
        let tmp1=num1[num1.length-1-i]; // num1尾元素
        for(let j=0;j<num2.length;j++){
            let tmp2 = num2[num2.length-1-j]; // num2尾元素
            let pos = res[i+j] ? res[i+j]+tmp1*tmp2 : tmp1*tmp2;// 目标值 ==》三元表达式,判断结果集索引位置是否有值
            res[i+j]=pos%10; // 赋值给当前索引位置
            // 目标值是否大于10 ==》是否进位 这样简化res去除不必要的"0"
            pos >=10 && (res[i+j+1]=res[i+j+1] ? res[i+j+1]+Math.floor(pos/10) : Math.floor(pos/10));
        }
    }
    return res.reverse().join("");
};

解题思路2 ==> ES10的新特性之一:BigInt(第8种数据类型)

JS 基本数据类型:BooleanNullUndefinedNumberStringSymbolObject
此新特性不做解题方法,只是告知有这个数据类型,毕竟题目要求不能使用任何标准库的大数类型,感谢楼下兄弟提醒。
image.png

代码

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var multiply = function(num1, num2) {
    return BigInt(num1)*BigInt(num2)+""
};