一天一大 lee(克隆图)难度:中等-Day20200813

时间:2022-07-25
本文章向大家介绍一天一大 lee(克隆图)难度:中等-Day20200813,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:

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

示例

  1. 示例 1
输入: num1 = "2", num2 = "3"
输出: "6"
  1. 示例 2
输入: num1 = "123", num2 = "456"
输出: "56088"

说明

  1. num1 和 num2 的长度小于 110。
  2. num1 和 num2 只包含数字 0-9。
  3. num1 和 num2 均不以零开头,除非是数字 0 本身。
  4. 由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q 也必须是节点 p 的邻居。
  5. 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

抛砖引玉

抛砖引玉

思路

  • 模拟乘法运算,逐位与另外字符逐位相乘
  • 存放乘积及两个数组的索引位置
  • 按索引位累加

实现

  • 声明 dp 记录位的乘积,长度为两数长度之和
  • num1 长 n,索引 i;num2 长 n,索引 j
  • dp[i+j+1] = num1[i]*num2[j]
  • 累加:
    • 有进位:dp[i+j] = dp[i+j]+进位值
    • 无进位:则不变
  • 注意:dp[i+j+1]的前一位是 dp[i+j]

特殊情况

  • 两数任意为 0,结果为 0
/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var multiply = function (num1, num2) {
  if (num1 === '0' || num2 === '0') return '0'
  let n = num1.length,
    m = num2.length
  dp = new Array(n + m).fill(0)

  for (let i = n - 1; i >= 0; i--) {
    for (let j = m - 1; j >= 0; j--) {
      // dp[i+j+1] 包含上一轮该乘积
      let sum = dp[i + j + 1] + parseInt(num1[i] * num2[j], 10)
      // 当前位i+j+1
      dp[i + j + 1] = parseInt(sum % 10, 10)
      // 上一位
      dp[i + j] = dp[i + j] + parseInt(sum / 10, 10)
    }
  }
  return dp.join('').replace(/^0*/, '')
}

做加法

  • 上面是逻辑是统一相乘,然后按存储位相加
  • 更直观的是从一个数字中取出一个元素与另外一个字符每一位相乘然后得到的字符每次累加
  • 字符串累加刚好又是几天前刚做的热乎的直接复用了字符串相加
/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var multiply = function (num1, num2) {
  if (num1 === '0' || num2 === '0') return '0'
  let n = num1.length,
    m = num2.length,
    _result = '0'

  for (let i = m - 1; i >= 0; i--) {
    let dp = [],
      jin = 0
    for (let j = m - 1; j > i; j--) {
      // 已处理位填充0
      dp.push(0)
    }
    for (let j = n - 1; j >= 0; j--) {
      // 单个位乘积
      let sum = parseInt(num2[i] * num1[j], 10) + jin
      dp.push(parseInt(sum % 10, 10))
      // 进位
      jin = parseInt(sum / 10, 10)
    }
    // 剩余进位
    if (jin) {
      dp.push(parseInt(jin % 10, 10))
    }
    // 累加
    _result = addStrings(_result, dp.reverse().join(''))
  }
  return _result

  // 字符串累加
  function addStrings(a, b) {
    let i = a.length - 1,
      j = b.length - 1,
      jin = 0,
      wei = 0,
      result = ''
    while (i >= 0 || j >= 0 || jin != 0) {
      const x = i >= 0 ? a.charAt(i) - '0' : 0
      const y = j >= 0 ? b.charAt(j) - '0' : 0
      wei = x + y + jin
      result = (wei % 10).toString() + result
      jin = parseInt(wei / 10, 10)
      i -= 1
      j -= 1
    }
    return result
  }
}