LeetCode每日1题--509. 斐波那契数

90 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情

前言

算法的重要性不言而喻!区分度高!

现在学习的门槛低了,只要能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。

说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!

推荐入门学习书籍:CPrimerPlus、大话数据结构

image-20220705103735001

刷题网站

代码随想录 (programmercarl.com)

leetcode

我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以

刷题嘛,最重要的就是坚持了!!!

画图软件

OneNote

这个要经常用,遇见不懂的流程的话就拿它画一画!

笔记软件

Typoral

题目

leetcode.cn/problems/fi…

image.png

解析

斐波那契数,我们举个例子

0,1,1,2,3,5,8....

有没有发现规律,就是F(n) = F(n - 1) + F(n - 2)

动态规划(dynamic planning)

动态规划一般的形式就是去求最值!比如最长什么什么,最短....,最省钱的...等等这些都是求最值问题。

如果说我们要求最值,那怎么求呢?其实就是穷举出所有的情况,然后选择最优情况,就是这个思路。但是如何穷举,如何保证效率?这又是我们需要考虑的...

动态规划相关的题目有很多重叠的子问题,比如这道题,你要求F(5)的值,那你就要求F(4)+F(3),求F(4)就要去求F(3)+F(2)...直到找到已知的值然后再回溯上去。像这种问题如果要暴力穷举的话其实时间复杂度是很高的,我们可以画二叉树来看下,时间复杂度都是指数级别的,如果要求F(20),那时间复杂度就是2的20次方!

image.png 原文链接:动态规划套路详解 - 斐波那契数 - 力扣(LeetCode)

这篇文章写的很好,看了很多文章都不知道动态规划啥意思,看了这一篇就明白了!

所以为了更好,更快的解题我们要对穷举进行优化,一般我们是使用DP数组去保存已知的数据,这样在进行计算的时候不需要再有递归的过程,而是去DP数组里查询就可以了。

image.png

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<=n;i++){
            dp[i] = dp[i-1] +dp[i-2];
        }
        return dp[n];


    }
}

状态转移公式

接下来说一下状态转移公式,这是个什么玩意,这么高级?

其实就是名字听起来高大上,我们把f(n)当做一个状态,这个状态呢是由f(n - 1) 和状态 f(n - 2) 相加转移而来,这就叫状态转移,

image.png

代码优化

其实我们发现这道题不需要new一个数组记录所有的结果,因为当前的状态只和之前的两个状态有关,我们其实只要记录之前的两个状态就可以了!这样可以把时间复杂度优化到O(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<=n;i++){
        //     dp[i] = dp[i-1] +dp[i-2];
        // }
        // return dp[n];

        // 状态压缩解法
        if(n < 2 ) return n;

        int pre = 0;
        int cur = 1;
        for(int i = 2; i <= n; i++){
            int sum = pre + cur;
            pre = cur;
            cur = sum;
        }
        return cur;
    }
}