LeetCode简单题Plus One JavaScript解法单测试用例未通过问题咨询
问题根源
你遇到的报错是JavaScript的Number类型精度限制导致的,不属于代码逻辑错误,也和JavaScript是否适合竞赛编程无关,只是对语言特性不熟悉导致的踩坑。
具体原因解释
JavaScript中所有常规数字都是以64位双精度浮点数的形式存储,能精确表示的整数范围是Number.MIN_SAFE_INTEGER(-9007199254740991)到Number.MAX_SAFE_INTEGER(9007199254740991),超出这个范围的整数会丢失精度,无法正确存储。
你未通过的测试用例拼接后的整数长度为19位,远大于最大安全整数的16位长度,转成Number类型时末尾几位已经失真,执行加1操作后自然得不到正确结果,这就是你输出末尾三位和预期不符的原因。
修复方案
有两种常用的修复思路:
方案1:遍历数组处理进位(兼容性最好,所有JS环境都支持)
直接从数组最低位(末尾)开始处理加1和进位逻辑,全程不需要转数字,完全规避精度问题:
var plusOne = function(digits) { let carry = 1; // 初始要加的1 for (let i = digits.length - 1; i >= 0 && carry; i--) { const sum = digits[i] + carry; digits[i] = sum % 10; carry = Math.floor(sum / 10); } // 所有位都进位的情况,比如[9,9]加1后变成[1,0,0] if (carry) digits.unshift(1); return digits; };
方案2:使用BigInt类型(ES2020及以上支持)
如果运行环境支持ES2020的BigInt类型,可以直接把你的原有代码里的Number替换成BigInt,就能避免精度丢失:
var plusOne = function(digits) { let num = BigInt(digits.join('')); num++; return num.toString().split('').map(Number); };
关于JavaScript竞赛适用性的说明
不存在JavaScript不适合竞赛编程的说法,只是它的隐式类型转换、浮点数精度等特性对不熟悉的开发者不友好,只要了解相关特性,完全可以用JavaScript完成各类算法题。
内容的提问来源于stack exchange,提问作者Harsh Mishra
相关产品推荐
相关产品推荐

