[上岸算法练习第一天]1 斐波那契数列

203 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目:

斐波那契数列

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

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

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1

示例 1:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

提示:

0 <= n <= 100

二、题解:

1.解读

从题目可以发现属于数学推导式,如果知道数学中的归纳法,不凡先看看它的规律。

n=0------> f(0)=0
n=1------> f(1)=1
n=2------> f(2)=f(0)+f(1)=1
n=3------> f(3)=f(2)+f(1)=2
F(N) = F(N - 1) + F(N - 2)

可以发现0和1相当于初始化数,后者依次等于前面两数之和,出现了递推的关系,故想到使用动态规划。

2.思路

确认了使用动态规划,则直接写出方程dp[i]=fun(dp[i-1],dp[i-2].....dp[i-m])。不过使用Dp的时候还是需要注意一下几点

  • 清楚dp的定义,这里的dp[i]代表什么含义
  • 确定状态转移方程,各个子问题之间的关系
  • 初始化dp数组
  • 模拟求解

3.实现

有了思路,我们下面开始详细写写实现过程

  • 确定此处dp的含义:dp为斐波那契数列记录数组,其中dp[i]表示下标为i的值
  • 确定状态转移方程,题目直接给出了转移方程的关系,即第n项的值为前两项的和,dp[i]=dp[i-1]+dp[i-2]
  • 初始化dp数组,条件已满足,即dp[0] = 0,dp[1] = 1
  • 模拟求解

三、代码:

class Solution:
    def fib(self, n: int) -> int:
        # 边界判断
        if(n<=1):
            return n
        
        # 第一步 确定dp[i]含义: 表示第i个对应的斐波那契数
        # 第二步 状态转移方程 dp[i] = dp[i-1] + dp[i-2]
        dp = [0]*(n+1)
        
        #第三步 初始化
        dp[0] = 0
        dp[1] = 1
​
        # S4 模拟递归
        for i in range(2, n+1):
            dp[i] = dp[i-1] + dp[i-2]
        
        return dp[i]%1000000007

时间复杂度:O(n) 二分查找的时间复杂度

空间复杂度:O(1) 使用了常数个空间

四、总结

采用动态规划的方式是因为自己想加强对动态规划的理解,其实还有其他诸如尾递归的方式。