力扣刷题笔记《动态规划篇》→ 509. 斐波那契数

583 阅读1分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

题目

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

F(0) = 0F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

给你 n ,请计算 F(n) 。

示例

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

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

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

提示

  • 0 <= n <= 30

解题思路

根据题目可以得出,从数值2开始,每一个数字都是由前面两位数字相加的和。那么,我们这里就可以得到两种解题方式:

  • 自顶向下:从F(n)出发,往0的方向延申

递归.png

  • 自底向上:从0出发,推导到F(n)

动态规划.gif

代码实现

方式一:递归

class Solution {
    public int fib(int n) {
        // 边界判断
        if(n < 2){
            return n;
        }
        // 向下递归,得到最终结果
        return fib(n - 1) + fib(n - 2);
    }
}

方式二:递归优化

方法一虽然简单,不过在递归的过程中会产生多次重复的计算,这里我们可以使用一个Map来保存每一次的计算结果,当遇上已经计算过的数值,则直接从Map中取出返回即可。

class Solution {
    private Map<Integer, Integer> map = new HashMap<>();
    public int fib(int n) {
        // 边界判断
        if(n < 2){
            return n;
        }
        // 判断当前数值是否递归过,如果是,则直接返回结果
        if(map.containsKey(n)){
            return map.get(n);
        }
        // 向下递归,得到最终结果
        int sum = fib(n - 1) + fib(n - 2);
        // 保存结果
        map.put(n, sum);
        return sum;
    }
}

方式三:动态规格

class Solution {
    public int fib(int n) {
        // 边界判断
        if(n < 2){
            return n;
        }
        
        int[] dp = new int[n + 1];
        // 初始化
        dp[1] = 1;
        // 向后推导,累加前面两数之和
        for(int i = 2; i <= n; ++i){
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        // 返回结果
        return dp[n];
    }
}

方式四:动态规格优化

在方式三中,我们定义了一个长度为n的数组,实际的计算过程中使用到的只有i之前的两位元素,那么我们可以定义两个变量用来存放前面的结果,省略掉其它的。

class Solution {
    public int fib(int n) {
        // 边界判断
        if(n < 2){
            return n;
        }
        
        int front = 0, after = 1, tmp;

        for(int i = 2; i <= n; ++i){
            // 更新状态
            tmp = after;
            after += front;
            front = tmp;
        }

        return after;
    }
}

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处:leetcode-cn.com/problems/fi…