LeetCode加一题目:数组转数字加1返回数组的代码部分数据集失效原因
加一问题代码错误分析
给定一个以整数数组
digits表示的大整数,其中digits[i]是该整数的第i位数字,数字按最高有效位到最低有效位的顺序从左到右排列,该大整数不包含任何前导0。请将该大整数加1,返回由结果数字组成的数组。测试示例:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:数组对应整数123,加1计算得124,返回对应数组即可。
原代码存在的问题
你的代码在普通长度的输入下可以正常运行,但遇到长数字、跨段进位的场景就会报错,核心问题有两个:
- 没有处理分段产生的进位传递。你把长度超过15的数字拆成前后两段,只给最后15位加1,完全没考虑最后15位全是9时,加1产生的进位需要加到前半段的情况。
比如输入是16个9组成的数组,你的代码截最后15个9加1得到1后面15个0,和前面剩下的第一个9拼接后得到错误结果[9,1,0,...0],正确结果应该是1后面16个0,总长度17位。
再比如输入是[1,2,3]拼接15个9,总长度18位,你的代码返回结果是[1,2,3,1,0,...0],正确结果应该是前三位123加进位1变成124,后面接15个0。 - 分段阈值的选择没有解决根本问题。你选15位作为拆分界限是为了规避JS中Number类型的精度丢失问题,但只要存在分段,就必须处理跨段进位,这部分逻辑完全缺失,自然会在对应测试用例上报错。
更可靠的实现方案
根本不需要把数组转成整数计算,直接从数组末尾向前遍历处理进位即可,完全绕开大数精度问题,代码也更简洁:
var plusOne = function(digits) { let carry = 1; // 初始要加的1就是初始进位 for (let i = digits.length - 1; i >= 0; i--) { const total = digits[i] + carry; digits[i] = total % 10; carry = Math.floor(total / 10); if (carry === 0) return digits; // 没有进位直接返回,不用继续遍历 } // 遍历完还有进位,说明全是9的情况,头部补1 if (carry === 1) digits.unshift(1); return digits; };
内容的提问来源于stack exchange,提问作者Ibleedcoffee
相关产品推荐
相关产品推荐

