【LeetCode-简单】509. 斐波那契数(详解)

题目

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fibonacci-number
【LeetCode-简单】509. 斐波那契数(详解)_第1张图片

方法1:递归

递归的方法很好理解:当n=0,那就返回0,当n=1,那就返回1,其余的都用前两个想加得出。

class Solution {
    public int fib(int n) {
        if (n == 0){
            return 0;
        }
        if (n == 1){
            return 1;
        }
        return fib(n - 1) + fib( n - 2);
    }
}

 【LeetCode-简单】509. 斐波那契数(详解)_第2张图片

效果不好,不推荐这种方法 

方法2:动态规划

这道题可以说是动态规划问题中比较简单的题,用动态规划来解题也是非常的方便。

这道题很适合 入门学习动态规划问题,因为题目已经将递推公式告诉我们了,很好写出来。

动态规划 三步走

动态规划,就是利用历史记录,来避免我们的重复计算。而这些历史记录,我们得需要一些变量来保存,一般是用一维数组或者二维数组来保存。下面我们先来讲下做动态规划题很重要的三个步骤,

1.定义dp数组

我们会用一个数组,来保存历史数组,假设用一维数组 dp[] 吧。这个时候有一个非常重要的点,就是规定你这个数组元素的含义,例如你的 dp[i] 是代表什么意思?

2.找出递推关系式

动态规划类似于高中数学的数学归纳法,当我们要计算 dp[n] 时,是可以利用 dp[n-1],dp[n-2]…..dp[1],来推出 dp[n] 的,也就是可以利用历史数据来推出新的元素值,所以我们要找出数组元素之间的关系式,例如 dp[n] = dp[n-1] + dp[n-2],这个就是他们的关系式了。

3.找出初始值

找出了递推公式,我们还需要初始值,因为递推公式就是靠前面的值推出后面的值,但总得有个头吧,这个头就是初始值。

提示

代码如何排错?将dp数组全部输出看看

1:dp数组:存储斐波那契计算结果

2:递推公式:题目直接给你了

3:初始值:dp[0]=0,dp[1]=1

class Solution {
    public int fib(int n) {
        if (n<2){
            return n;
        }
        int dp[] = new int[n+1];
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i < dp.length; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

【LeetCode-简单】509. 斐波那契数(详解)_第3张图片

可以看到效果比递归好了不少,动态规划 win! 

方法3:动态规划优化

从方法2的动态规划中我们不难发现:每个数都是由它前两个数得出的,所以我们不用维护整个数组,我们只需要维护长度为3的数组即可。

class Solution {
    public int fib(int n) {
        if (n < 2) {
            return n;
        }
        int num1 = 0;
        int num2 = 1;
        int sum = num1 + num2;

        for (int i = 2; i <= n; i++) {
            sum = num1 + num2;
            num1 = num2;
            num2 = sum;
        }
        return sum;
    }
}

【LeetCode-简单】509. 斐波那契数(详解)_第4张图片

你可能感兴趣的:(LeetCode,leetcode,算法,职场和发展)