JavaScript函数返回正确但while循环超时问题排查求助
问题分析与优化方案
首先得说,你的功能逻辑是对的,但超时的罪魁祸首绝对是频繁调用values.shift()——这个方法看起来简单,但背后的性能开销很大:每次调用它,数组都要把所有剩余元素向前移动一位来填补被移除的第一个元素的位置,时间复杂度是O(k)(k是当前数组的长度)。当输入的values数组很大时,你反复在while循环里调用shift,总时间复杂度会飙升到O(m²)(m是values的初始长度),这就触发了超时限制。
再看看你代码里的其他小问题:
- while循环的逻辑有点冗余,你其实不需要反复循环数组来分配金额,一次遍历就能搞定
- 处理
n > values.length时的remainder逻辑有点绕,其实可以更简洁
优化后的高效代码(无超时)
function beggars(values, n) { // 处理n为0的边界情况(原代码没覆盖,可选但更健壮) if (n === 0) return []; // 初始化结果数组,每个乞丐初始金额为0 const result = new Array(n).fill(0); // 遍历所有金额,按顺序分配给对应乞丐 values.forEach((amount, index) => { // 计算当前金额属于第几个乞丐:索引取模n const beggarIdx = index % n; result[beggarIdx] += amount; }); return result; }
为什么这个版本不会超时?
- 时间复杂度降到O(m):只需要遍历一次
values数组,每个元素的分配操作都是O(1)的,不管数组多大,都能快速完成。 - 不修改原数组:避免了
shift()带来的数组重排开销,也不会破坏原输入数据。 - 自动处理所有边界情况:
- 当
n=1时,所有元素都会加到result[0]上,和你原逻辑一致 - 当
n > values.length时,后面的乞丐保持初始的0,不需要额外补0操作 - 当
values为空时,直接返回n个0的数组
- 当
原代码的其他可改进点
你原代码里while循环中,当values.length < n时的for循环条件i <= values.length + 1可能会导致多循环一次(比如剩下2个元素时,i会到3,此时shift得到undefined,加到obj[i]里会变成NaN),不过你说功能正常,可能测试用例没覆盖到这种情况,但优化后的代码完全避免了这类问题。
内容的提问来源于stack exchange,提问作者Sam Parsons
相关产品推荐
相关产品推荐

