题目描述

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。

示例 2:

输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。

示例 3:

输入:digits = [0]
输出:[1]
力扣原题目地址:https://leetcode.cn/problems/...

使用Bigint解决大数精度丢失问题

当本宗看到此题时,顿时黑人问号涌上心头,什么?这么简单的力扣题目,不会吧!不会吧!(白岩松式疑惑)这不就是:

  1. 把数组转化成字符串再转成数字,然后加一(因为数字才能加一)
  2. 然后再把数字转回去,转成数组

于是乎,本宗祭出飞天指法,敲击在本宗秘宝、远古仙器机械茶轴键盘上,霎时间,诡异的声响直冲云霄,恐怖的威压席卷大地。周遭一些实力不济的程序猿兽,一口鲜血从七窍喷涌而出,身体倒飞而出,在地上犁出一条长几十米深半米多的沟壑,最终狠狠地撞击在公司杂物间的墙壁上,带起漫天烟尘。烟尘散去,条条密密麻麻蛛网般的裂痕爬满墙壁。三秒后,苦苦支撑的皲裂墙壁终于轰然倒塌,将哪些气若游丝的程序员兽埋在废墟下方,不知死活。

本宗不禁大喜,飞天指法,恐怖如斯、仙器键盘,强悍至此!

本宗心神一动,须臾间,玄而又玄的代码便是凭空出现:

var plusOne = function (digits) { 
    digits = digits.join('') * 1 // 数组转字符串再转数字
    digits = digits + 1 // 数字加一
    return (digits + '').split('') // 再把数字转成字符串并分割成数组即可
};

本宗得意的望着自己创造出的玄妙代码,捋了捋胡须,从容不破的点了提交,本以为会成功通过,但是接下来的画面,让本宗倒吸一口凉气:

没通过测试用例!

本宗眉头一皱,发现这道题并没有这么简单,因为本宗突然想起来远古斗码大陆流传的一部《玄天js古经书》,书中有这样一段晦涩难懂的真奥之理:

js中数字类型无法表示大数,即超过16位数字,会出现精度丢失问题

果然如此!

报错的用例是达到了恐怖的19位数,远超16位啊,所以出现精度丢失,所以答案不正确。

看来出题人应该就是传说中的bug强者!本宗纵横此斗码大陆多年,没想到今天居然阴沟里翻车,若传出去本宗颜面何在?岂不叫小辈贻笑大方?

不行,本宗心一横,心中盘算道:此问题不能留!

忽然,虚空中一道苍老的声音传出:吾乃代码老怪,感觉与你颇有机缘,今日赠你一部js修炼大法《M帝恩》!

多写前辈大恩,本宗就勉为其难收下了。

不知何时,本宗的电脑屏幕上多了一个链接:https://developer.mozilla.org...

先不管这么多了,此人到没有恶意...

于是在js修炼大法《M帝恩》的帮助下,本宗解决了这道题

var plusOne = function (digits) { 
    let number = BigInt(digits.join('')); // 使用BigInt防止精度丢失
    number = number + BigInt(1) // BigInt与BigInt同类型相加
    let res = (number + '').split('') // 再转回数组即可
    return res 
};

相比较上方的错误做法,其就是使用了Bigint对象,去解决超过16位的大数问题。所以大家在遇到大数问题的时候,就可以考虑使用bigint对象去控制,这样的话,就不会精度丢失哦。关闭bigint的知识点,在这里就不赘述了,大家可以在上方的MDN连接上看一下

力扣刷题其实挺无聊的,所以写一篇“代码修仙文”,供大家一乐^_^


水冗水孚
1.1k 声望585 粉丝

每一个不曾起舞的日子,都是对生命的辜负