实现斐波那契数列逐步降维打击

斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给你 n ,请计算 F(n) 。

示例 1:

输入:2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2:

输入:3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3:

0 <= n <= 30来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/fibonacci-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一:直接“傻递归”

为什么叫傻递归,最大原因是存在大量大量的重复计算。详细请自己画画递归树,自己推一推。

自顶向上,存在大量重复的计算

分析:

​ 1. 时间复杂度: O(2^n)

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
    if (n === 0 || n === 1) return n;
    if (n === 2) return 1;
    return fib(n-1) + fib(n-2);
};

解法二:聪明递归

针对以上的傻递归,设置一个数组memo或者哈希表来存储中间结果,计算的时候看是否在memo中含有结果,如果有的话就直接返回

事件复杂度: 0(n)

空降复杂度:0(n) 空间换时间的一个案例

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
	const memo = [];
  return helper(memo,n);
};
function helper(memo,n) {
  if (n === 1 || n === 0) return n;
  if (n === 2) return 1;
  // 先查表
  if (memo[n]) return memo[n];
  memo[n] = helper(memo,n-1) + helper(memo,n-2);
  return memo[n];
}

方法三:使用动态规划

f(0) = 0 f(1) = 1 f(2) = 1 f(n) = f(n-1) + f(n-1);

时间复杂度: 0(n)

空间复杂度: 0(n)

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
  	const memo = [];
  	memo[0] = 0;
  	memo[1] = 1;
  	memo[2] = 1;
  	for(let i = 3; i <= n; ++i) {
      memo[i] = memo[i-1] + memo[i-2];
    }
  return memo[n];
};

方法四:压缩状态

由状态方程可以知道,结果只有两个状态有关,即 n-1和n-2

时间复杂度: 0(n)

空间复杂度:0(n)

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
    let first = 0,second = 1,result;
    if (n === 0 || n === 1) return n;
    for(let i = 2; i <= n; ++i) {
        result = first + second;
        first = second;
        second = result;
    }
    return result;
};

总结

​ 斐波那契问题是动态规划的一个很好的切入点,但是它还不是动态规划的问题,因为它没有求最值的要求。

但是我们可以学习的是,第一找到状态转义方程,然后进行傻递归,然后设置备忘录去进行一个优化递归,然后进行一个动态规划的思路,最后去进行动态规划的优化。方法一到方法四十完全是沿着这条路一直走下来的。一步一步实现降为打击。官方题解中还有两种较为高级的解法,对数学要求相当的高,可以去看看!

参考

  • 《labuladong的算法小抄》

  • leetcode官方题解

慢慢来,比较快!基础要牢,根基要稳!向大佬致敬!
原文地址:https://www.cnblogs.com/rookie123/p/14651182.html