美文网首页
leetcode算法-给定两个字符串形式的非负整数 num1 和

leetcode算法-给定两个字符串形式的非负整数 num1 和

作者: Weastsea | 来源:发表于2020-04-26 15:06 被阅读0次

说明

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

num1 和num2 的长度都小于 5100.
num1 和num2 都只包含数字 0-9.
num1 和num2 都不包含任何前导零。
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。

解题:

初次看到这个题目,没有考虑到大数相加问题,所以直接的思路是:

  • 字符串转化为数组,然后反转
  • 循环遍历数组,从数组第二位开始,依次乘以Math.pow(10, i)

具体实现如下:

var addStrings = function (num1, num2) {
    const num1Arr = num1.split('').reverse()
    const num2Arr = num2.split('').reverse()
    let sum1 = 0
    let sum2 = 0
    for (let i = 0; i < num1Arr.length; i++) {
        if (!i) {
            sum1 += parseInt(num1Arr[i])
        } else {
            sum1 += parseInt(num1Arr[i]) * Math.pow(10, i)
        }
    }
    for (let i = 0; i < num2Arr.length; i++) {
        if (!i) {
            sum2 += parseInt(num2Arr[i])
        } else {
            sum2 += parseInt(num2Arr[i]) * Math.pow(10, i)
        }
    }
    const total = sum1 + sum2
    return total + ''
}

但是执行leetcode的测试用例,没有通过,挂在了addStrings('9333852702227987', '85731737104263')这两个数据的计算上。如下图所示:

看到这里,让我想到了这应该是大数相加的问题,那我们一起再学习一下大数相加的问题吧,然后我们再解题:

大数相加问题

因为JavaScriptNumber类型是遵循IEEE 754规范表示的,这就意味着JavaScript能精确表示的数字是有限的,JavaScript可以精确到个位的最大整数是9007199254740992,也就是2的53次方,超过这个范围就会精度丢失,造成JavaScript无法判断大小,从而会出现下面的现象

Math.pow(2, 53);    // 9007199254740992
Math.pow(2, 53) === Math.pow(2, 53) + 1;    // true
9007199254740992 === 9007199254740992 + 1;    // true

在网上找了一张图,表示的比较形象,也不知道来源是哪里的,很多人的博客里都有这张图,我们也借来参考下:


从图中可以看到当正数大于2^53时,已经无法精确的表示到个位。

解决方案

解决方案思路其实比较简单,就是将字符串转换为数组,末尾对齐,数组的两两元素相加得到total,如果total大于10的话,就往下一位进1,本次计算这一位对10求余数(temp % 10) + res做拼接。最后得到的结果就是精确的。通过这个思路,可以实现下leetcode这道题,本质也是大数相加问题:

var addStrings = function (num1, num2) {
    // 数组的两两元素相加得到total,如果total大于10的话,就往下一位进total-10
    let res = ''
    let carry = 0
    let i = num1.length - 1
    let j = num2.length - 1
    while (i >= 0 || j >= 0) {
        let temp = Number(num1[i]) + Number(num2[j]) + carry
        if (i < 0) {
            temp = Number(num2[j]) + carry
            i = 0
        }
        if (j < 0) {
            temp = Number(num1[i]) + carry
            j = 0
        }
        // 从后往前记录数组的两两元素相加得到total,如果total大于10的话,下一次计算需要进1
        carry = temp >= 10 ? 1 : 0
        // 数组的两两元素相加得到total,如果total大于10的话,当前位就保留total-10(temp % 10)
        res = (temp % 10) + res
        i--
        j--
    }
    return carry > 0 ? `${carry}${res}` : `${res}`
}

执行效率如下图所示:


相关文章

  • LeetCode-043-字符串相乘

    字符串相乘 题目描述:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的...

  • leetcode 43. 字符串相乘(Java版)

    题目描述(题目难度,中等) 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num...

  • 43.字符串相乘

    题目描述: 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们...

  • 415-字符串相加

    字符串相加 题目 给定两个字符串形式的非负整数num1 和num2,计算它们的和。 注意: num1 和num2的...

  • [LeetCode]43、字符串相乘

    题目描述 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的...

  • PHP-字符串相乘

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

  • 字符串相乘

    题目描述:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的...

  • LeetCode 43.字符串相乘

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

  • LeetCode - 43. 字符串相乘

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

  • LeetCode 43. 字符串相乘

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

网友评论

      本文标题:leetcode算法-给定两个字符串形式的非负整数 num1 和

      本文链接:https://www.haomeiwen.com/subject/ksgdwhtx.html