斐波那契数列

118 阅读1分钟

1.根据公式,直接递归

/**
 * 斐波那契数列 F(1)=1 F(2)=1 F(n)=F(n-2)+F(n-1)
 */

/**
 * 递归
 */
function Fibonacci_1(n) {
  if (n <= 1) {
    return n;
  }
  return Fibonacci_1(n - 2) + Fibonacci_1(n - 1);
}
console.time("Fibonacci_1");
Fibonacci_1(40);
console.timeEnd("Fibonacci_1"); //Fibonacci_1: 899.942ms

简单,根据公式直接写出,但是慢。
时间复杂度:O(2^n)
空间复杂度:递归栈的空间

2.不递归,保存重复计算结果

/**
 * 保存计算结果
 */

let map = new Map();

function fib(n) {
  let a;
  if (map.has(n)) {
    a = map.get(n);
  } else {
    a = Fibonacci_2(n);
    map.set(n, a);
  }
  return a;
}

function Fibonacci_2(n) {
  if (n <= 1) {
    return n;
  }
  return fib(n - 2) + fib(n - 1);
}

console.time("Fibonacci_2");
Fibonacci_2(40);
console.timeEnd("Fibonacci_2"); //Fibonacci_2: 0.217ms

可以看到速度比递归快了很多
时间复杂度:O(n)没有重复的计算
空间复杂度:O(n)和递归栈的空间

3.动态规划

/**
 * 动态规划
 * @param {number}} n
 */

function Fibonacci_3(n) {
  // write code here F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)
  if (n <= 1) {
    return n;
  }
  let a = 0,
    b = 1,
    c;
  for (let i = 2; i <= n; i++) {
    c = a + b;
    a = b;
    b = c;
  }
  return c;
}

console.time("Fibonacci_3");
Fibonacci_3(40);
console.timeEnd("Fibonacci_3"); //Fibonacci_3: 0.143ms

耗时最短。将计算过程拆解,每次计算只需要F(n-2)和F(n-1)的计算结果,不需要存储所有的计算结果。
时间复杂度:O(n)
空间复杂度:O(1)