JavaScript递归生成斐波那契数列数组的优化问题
嘿,我完全懂你对那个硬编码arr=[0]的别扭感——确实不够干净!咱们来把它干掉,同时让函数输出正确的斐波那契数组。
你改成arr=[]后缺失开头的0,核心问题出在base case的处理逻辑上。原代码里当n===0或n===1时直接往空数组里pushn,但n=1时这样得到的是[1],而正确的初始数组应该是[0,1],这就导致后续递归拼接时丢失了开头的0。
方案1:简洁递归(无硬编码初始数组)
这个版本直接通过递归构建数组,逻辑更清晰,也不需要依赖默认参数里的硬编码初始值:
function fib(n) { // 基础情况:n=0返回只包含0的数组 if (n === 0) { return [0]; } // n=1返回完整的初始斐波那契数组 if (n === 1) { return [0, 1]; } // 递归获取到n-1的数组 const previousArray = fib(n - 1); // 计算下一个元素:数组最后两项的和 const nextNumber = previousArray[previousArray.length - 1] + previousArray[previousArray.length - 2]; // 返回新数组(纯函数,不修改原数组) return [...previousArray, nextNumber]; }
测试效果:
fib(0)→[0]fib(1)→[0, 1]fib(3)→[0, 1, 1, 2]fib(5)→[0, 1, 1, 2, 3, 5]
方案2:尾递归累积版本(初始arr=[])
如果想保留原函数的参数累积风格,这个版本用尾递归实现,完全去掉了硬编码的初始值:
function fib(n, arr = []) { // 第一次调用时初始化数组 if (arr.length === 0) { if (n === 0) return [0]; // 填充初始的两个斐波那契数 arr.push(0, 1); // 如果n是1,直接返回初始化后的数组 if (n === 1) return arr; } // 终止条件:数组长度已经覆盖到第n项(从0开始共n+1个元素) if (arr.length === n + 1) return arr; // 计算下一个元素并添加到数组 const next = arr[arr.length - 1] + arr[arr.length - 2]; arr.push(next); // 尾递归调用,继续累积 return fib(n, arr); }
这个版本的测试结果和上面完全一致,而且初始arr是干净的空数组,没有硬编码的0。
另外提一句:原代码同时调用fib(n-1)和fib(n-2)的分治方式会带来大量重复计算,效率较低,上面的两种方案都是基于fib(n-1)来构建数组,避免了重复计算,性能会更好。
内容的提问来源于stack exchange,提问作者Joji
相关产品推荐
相关产品推荐

