You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:29:09