每日算法:字符串相乘

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

[[421393]]

本文转载自微信公众号「三分钟学前端」,作者sisterAn。转载本文请联系三分钟学前端公众号。

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

示例 1:

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

示例 2:

输入: num1 = "123", num2 = "456" 
输出: "56088" 
  • 1.
  • 2.

说明:

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

解法一:常规解法

从右往左遍历乘数,将乘数的每一位与被乘数相乘得到对应的结果,再将每次得到的结果累加

另外,当乘数的每一位与被乘数高位(非最低位)相乘的时候,注意低位补 '0'

let multiply = function(num1, num2) { 
    if (num1 === "0" || num2 === "0"return "0" 
     
    // 用于保存计算结果 
    let res = "0" 
         
    // num2 逐位与 num1 相乘 
    for (let i = num2.length - 1; i >= 0; i--) { 
        let carry = 0 
        // 保存 num2 第i位数字与 num1 相乘的结果 
        let temp = '' 
        // 补 0  
        for (let j = 0; j < num2.length - 1 - i; j++) { 
            temp+='0' 
        } 
        let n2 = num2.charAt(i) - '0' 
             
        // num2 的第 i 位数字 n2 与 num1 相乘 
        for (let j = num1.length - 1; j >= 0 || carry != 0; j--) { 
            let n1 = j < 0 ? 0 : num1.charAt(j) - '0' 
            let product = (n1 * n2 + carry) % 10 
            temp += product  
            carry = Math.floor((n1 * n2 + carry) / 10) 
        } 
        // 将当前结果与新计算的结果求和作为新的结果 
        res = addStrings(res, Array.prototype.slice.call(temp).reverse().join("")) 
    } 
    return res 

 
let addStrings = function(num1, num2) { 
    let a = num1.length, b = num2.length, result = '', tmp = 0 
    while(a || b) { 
        a ? tmp += +num1[--a] : '' 
        b ? tmp +=  +num2[--b] : '' 
         
        result = tmp % 10 + result 
        if(tmp > 9) tmp = 1 
        else tmp = 0 
    } 
    if (tmp) result = 1 + result 
    return result 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

复杂度分析:

  • 时间复杂度:O(max(m*n , n * n))
  • 空间复杂度:O(m+n)

解法二:竖式相乘(优化)

两个数M和N相乘的结果可以由 M 乘上 N 的每一位数的和得到 ,如下图所示:

  • 计算 num1 依次乘上 num2 的每一位的和
  • 把得到的所有和按对应的位置累加在一起,就可以得到 num1 * num2 的结果
let multiply = function(num1, num2) { 
    if(num1 === '0' || num2 === '0'return "0" 
     
    // 用于保存计算结果 
    let res = [] 
     
    // 从个位数开始逐位相乘 
    for(let i = 0 ; i < num1.length; i++){ 
        // num1 尾元素 
        let tmp1 = +num1[num1.length-1-i] 
         
        for(let j = 0; j < num2.length; j++){ 
            // num2尾元素 
            let tmp2 = +num2[num2.length-1-j] 
             
            // 判断结果集索引位置是否有值 
            let pos = res[i+j] ? res[i+j]+tmp1*tmp2 : tmp1*tmp2 
            // 赋值给当前索引位置 
            res[i+j] = pos%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(""); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

复杂度分析:

 

  • 时间复杂度:O(m * n)
  • 空间复杂度:O(m + n)

 

责任编辑:武晓燕 来源: 三分钟学前端
相关推荐

2021-09-10 08:31:54

翻转字符串单词

2021-08-26 05:08:25

相邻重复项算法

2021-09-02 09:22:13

算法无重复字符

2016-12-30 13:32:24

字符串算法代码

2023-12-15 10:27:01

暴力匹配算法Python字符串

2013-05-06 10:54:08

字符串字符串匹配KMP算法

2023-02-26 22:33:32

字符串排列算法

2021-11-12 09:44:03

字符串算法复杂度

2023-04-11 08:54:57

字符串匹配算法

2016-12-30 13:16:51

字符串算法代码

2024-07-03 11:23:14

2013-05-06 10:49:21

Boyer-Moore算法字符串匹配

2009-08-11 10:26:49

C#算法C#字符串反转

2016-12-30 13:37:50

字符串算法代码

2021-12-21 11:39:01

数据结构算法同构字符串

2009-06-23 14:13:00

Java字符串

2024-04-01 08:41:39

字符串.NET

2021-12-24 11:59:47

数据结构算法字符串

2010-09-09 11:48:00

SQL函数字符串

2021-03-08 08:23:24

Java字符串截取
点赞
收藏

51CTO技术栈公众号