相信很多小伙伴刷题的时候面对力扣上近两千到题目,感觉无从下手,我花费半年时间整理了leetcode刷题指南,不仅有详细经典题目刷题顺序而且对应题解来排好了,难点还有视频讲解,按照list一道一道刷就可以了,绝对是最强攻略!

509. 斐波那契数

题目地址:https://leetcode-cn.com/problems/fibonacci-number/

斐波那契数,通常用 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:
输入:4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3

提示:

  • 0 <= n <= 30

思路

斐波那契数列大家应该非常熟悉不过了,非常适合作为动规第一道题目来练练手。

因为这道题目比较简单,可能一些同学并不需要做什么分析,直接顺手一写就过了。

但「代码随想录」的风格是:简单题目是用来加深对解题方法论的理解的

通过这道题目让大家可以初步认识到,按照动规五部曲是如何解题的。

对于动规,如果没有方法论的话,可能简单题目可以顺手一写就过,难一点就不知道如何下手了。

所以我总结的动规五部曲,是要用来贯穿整个动态规划系列的,就像之前讲过二叉树系列的递归三部曲,回溯法系列的回溯三部曲一样。后面慢慢大家就会体会到,动规五部曲方法的重要性。

动态规划

动规五部曲:

这里我们要用一个一维dp数组来保存递归的结果

  1. 确定dp数组以及下标的含义

dp[i]的定义为:第i个数的斐波那契数值是dp[i]

  1. 确定递推公式

为什么这是一道非常简单的入门题目呢?

因为题目已经把递推公式直接给我们了:状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];

  1. dp数组如何初始化

题目中把如何初始化也直接给我们了,如下:

dp[0] = 0;
dp[1] = 1;
  1. 确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的

  1. 举例推导dp数组

按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2],我们来推导一下,当N为10的时候,dp数组应该是如下的数列:

0 1 1 2 3 5 8 13 21 34 55

如果代码写出来,发现结果不对,就把dp数组打印出来看看和我们推导的数列是不是一致的。

以上我们用动规的方法分析完了,C++代码如下:

class Solution {
public:int fib(int N) {if (N <= 1) return N;vector<int> dp(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];}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

当然可以发现,我们只需要维护两个数值就可以了,不需要记录整个序列。

代码如下:

class Solution {
public:int fib(int N) {if (N <= 1) return N;int dp[2];dp[0] = 0;dp[1] = 1;for (int i = 2; i <= N; i++) {int sum = dp[0] + dp[1];dp[0] = dp[1];dp[1] = sum;}return dp[1];}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

递归解法

本题还可以使用递归解法来做

代码如下:

class Solution {
public:int fib(int N) {if (N < 2) return N;return fib(N - 1) + fib(N - 2);}
};
  • 时间复杂度:O(2^n)
  • 空间复杂度:O(n) 算上了编程语言中实现递归的系统栈所占空间

这个递归的时间复杂度大家画一下树形图就知道了,如果不清晰的同学,可以看这篇:通过一道面试题目,讲一讲递归算法的时间复杂度!

总结

斐波那契数列这道题目是非常基础的题目,我在后面的动态规划的讲解中将会多次提到斐波那契数列!

这里我严格按照关于动态规划,你该了解这些!中的动规五部曲来分析了这道题目,一些分析步骤可能同学感觉没有必要搞的这么复杂,代码其实上来就可以撸出来。

但我还是强调一下,简单题是用来掌握方法论的,动规五部曲将在接下来的动态规划讲解中发挥重要作用,敬请期待!

就酱,循序渐进学算法,认准「代码随想录」!

我是程序员Carl,可以找我组队刷题,也可以在B站上找到我,本文leetcode刷题攻略已收录,更多精彩算法文章尽在公众号:代码随想录,关注后就会发现和「代码随想录」相见恨晚!

如果感觉对你有帮助,不要吝啬给一个

「力扣」509. 斐波那契数【动态规划】详解!相关推荐

  1. 力扣算法 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

    学习内容 力扣算法 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 具体内容 509. 斐波那契数 斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 .该数列由 0 ...

  2. 【快乐水题】509. 斐波那契数

    原题: 力扣链接:509. 斐波那契数 题目简述: 斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 .该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就是: F( ...

  3. LeetCode-动态规划基础题-509. 斐波那契数

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

  4. D38| DP理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

    DP理论基础 重要知识点: 1.动规和贪心的区别:动规是由前一个状态推导出来的,而贪心是局部直接选最优的 2.动规五部曲: 1)确定dp数组(dp table)以及下标的含义 2)确定递推公式 3)d ...

  5. 代码随想录算法训练营第三十八天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯。

    Leetcode 509. 斐波那契数 题目链接:509. 斐波那契数 class Solution {public:int fib(int n) {if(n <= 1)return n;int ...

  6. [leetcode]509. 斐波那契数

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

  7. leetcode 509. 斐波那契数

    方法一:递归 使用递归计算给定整数的斐波那契数. 效率最差但是最简单的方法,会重复计算,就不实现了. 方法二:记忆化自底向上的方法 方法三:自底向上进行迭代 方法四:矩阵求幂 public class ...

  8. leetcode 509. 斐波那契数(dfs)

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

  9. leetcode 509. 斐波那契数(Fibonacci Number)

    目录 题目描述: 示例 1: 示例 2: 示例 3: 解法: 题目描述: 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列.该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的 ...

  10. 509. 斐波那契数

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

最新文章

  1. 【Qt】Qt样式表总结(一):选择器
  2. centos 6.1_64位系统 双网卡邦定
  3. 光敏电阻检测12528
  4. GIS输出PDF为什么标注有问题
  5. [c语言 ] 用libev 写个echo服务器
  6. 曙光服务器2008系统,在中科曙光I620-G20服務器上安裝Windows 2008 R2 系統步驟
  7. 环信集成 2---基于环信Demo3.0,实现单聊功能
  8. HTML form的一些属性(第一版)
  9. 【专升本计算机】甘肃省专升本计算机C语言经典程序案例代码合集(持续更新)
  10. Python内置数据类型之list
  11. Linux内核启动去掉企鹅,修改linux内核kernel开机logo(小企鹅)
  12. mysql联合索引和单索引_mysql联合索引跟单列索引的区别
  13. JS中调用bignumber处理高精度小数运算
  14. Linux:查看内存和CPU信息
  15. 评分卡模型之数据预处理
  16. matlab画图画点画直线
  17. dqo变换_一种基于dqo变换改进的电流检测新方法
  18. 基于海量特征向量数据搜索引擎(达到毫秒级)
  19. 双目测距算法matlab模拟,基于BM算法的双目测距.pdf
  20. mysql键值_如何在MySQL中存储键值对?

热门文章

  1. 配置nginx负载均衡
  2. 关于在EF中通用方法
  3. Python + Selenium 自动发布文章(一):开源中国
  4. selenium中CSS选择器定位
  5. Xcode CoreData 存储报错问题。
  6. [转]关于SilverLight:你需要知道的十件事情
  7. Denise God Mode for mac(磁带饱和器音频插件)
  8. Mac快速备忘录开启与关闭设置方法
  9. macOS Big Sur在APFS格式的驱动器上支持Time Machine有几个问题?
  10. Android自定义控件封装之自定义属性的实现