目 录CONTENT

文章目录

509. 斐波那契数

小王同学
2023-12-29 / 0 评论 / 0 点赞 / 46 阅读 / 0 字

509. 斐波那契数

【简单题】

传送门:509. 斐波那契数

斐波那契数,通常用 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这个数组,该类题目重点要理解dp[]数组中存的元素的含义,否则将会很迷

我们来看这道题目:

首先题目给了**“该数列由 0 和 1 开始”**,看到这里我们就要想到初始化两个默认值,并且需要考虑F(0)和F(1)的特殊情况。接着我们需要准备dp数组,dp数组的大小如何确定呢?为什么是n+1,而不是n呢?我们下面解答。

  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数组打印出来看看和我们推导的数列是不是一致的。

以上我们用动规的方法分析完了

代码实现:

/**
 * 509. 斐波那契数
 *
 */
public class FibonacciNumbers {
        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];
        }
}

最后我们解释一下上面的问题,dp数组的大小如何确定呢?为什么是n+1,而不是n呢?

在这个实现中,数组的索引表示斐波那契数的位置,数组的值存储相应位置的斐波那契数。由于数组的索引从0开始,所以需要一个长度为n+1的数组,以便能够存储从第0个到第n个斐波那契数,共计n+1个数。

例如,当n=5时,需要一个长度为6的数组来存储从第0个到第5个斐波那契数,即dp[0],dp[1],dp[2],dp[3],dp[4],dp[5]。

因此,初始化int数组为n+1的目的是为了确保数组的长度足够存储从第0个到第n个斐波那契数。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区