LeetCode 509. 斐波那契数
一、题目
1、题目描述
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给定 n ,请计算 F(n) 。
示例 1:
输入:n = 2 输出:1 解释:F(2) = F(1) + F(0) = 1 + 0 = 1 示例 2:
输入:n = 3 输出:2 解释:F(3) = F(2) + F(1) = 1 + 1 = 2 示例 3:
输入:n = 4 输出:3 解释:F(4) = F(3) + F(2) = 2 + 1 = 3
提示:
0 <= n <= 30
2、基础框架
- C++语言 版本给出的基础框架代码如下:
class Solution {public: int fib(int n) { }};
3、原题链接
LeetCode 509. 斐波那契数
二、解题报告
1、思路分析
( 1 ) 暴力递归:代码简洁,但是十分低效,以n = 20作出递归树,先算出子问题 f(19) 和 f(18) ,这里需要先计算出 f(19) ,那么需要先计算出 f(18) 和 f(17),这里我们可以看出,f(18) 被计算了两遍
( 2 ) 动态规划 - 重叠子问题:使用一个数组充当备忘录
2、时间复杂度
( 1 )暴力递归: O(2^n);
( 2 )动态规划 - 重叠子问题:O(n)
3、代码详解
class Solution {public: int fib(int N) { if (N < 1) return 0; // 备忘录全初始化为 0 vector<int> memo(N + 1, 0); // 进行带备忘录的递归 return helper(memo, N);} int helper(vector<int>& memo, int n) { // base case if (n == 1 || n == 2) return 1; // 已经计算过 if (memo[n] != 0) return memo[n]; memo[n] = helper(memo, n - 1) + helper(memo, n - 2); return memo[n];}};
- ( 1 ) 一般使用数组充当【备忘录】,当然也可以使用哈希表
- ( 2 ) 带「备忘录」的递归算法,把⼀棵存在巨量冗余的递归树通过「剪枝」,改造成了⼀幅不存在冗余的递归图,极⼤减少了⼦问题(即递归图中节点)的个数。
三、本题小知识
递归,动态规划