剑指 Offer 10- I. 斐波那契数列


一、题目

写一个函数,输入 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.递归

class Solution:
    #递归
        #1.确定递归函数参数和返回值
    def fib(self, n: int) -> int:
        #2.确定递归函数的终止条件
        if n==0:
            return 0
        if n==1:
            return 1
        
        #3.确定单层递归的逻辑
        return self.fib(n-1)+self.fib(n-2)

出现问题:
(1)递归深度过大的话,容易导致栈溢出
(2)会进行大量重复操作
  F(5)=F(4)+F(3)
        F(4)=F(3)+F(2)
              F(3)=F(2)+F(1)
              F(2)=F(1)+F(0)
        F(3)=F(2)+F(1)

2.动态规划

1.动态规划解析:

  1. 状态定义: 设 dp为一维数组,其中 dp[i]的值代表 斐波那契数列第 i 个数字 。
  2. 转移方程: dp[i + 1] = dp[i] + dp[i - 1],即对应数列定义 f(n + 1) = f(n) + f(n - 1) ;
  3. 初始状态: dp[0] = 0, dp[1] = 1 ,即初始化前两个数字;
  4. 返回值: dp[n] ,即斐波那契数列的第 n个数字。

2.动态规划五部曲:

公众号:代码随想录
https://mp.weixin.qq.com/s/ko0zLJplF7n_4TysnPOa_w

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

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

    #下标表示第i项的值,从第0项开始 ---> 第n项, 共n+1项
    dp=[0]*(n+1)

2.确定递归公式

    dp[n]=dp[n-1]+dp[n-2]
  1. dp数组如何初始化

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

    #从前向后遍历
    #从i=2,到i=n
    
  3. 举例推导dp数组

    dp[2]=dp[1]+dp[0]
    dp[3]=dp[2]+dp[1]
    
    #打印dp数组
    N=10,dp: 0 1 1 2 3 5 8 13 21 34 55
    
    #将状态转移在dp数组上模拟

使用数组存储已经计算的结果,避免重复计算。

class Solution:
    
    def fib(self, n: int) -> int:
        #  1.动态规划
		#当n=0和1时,n-1为-1和0
        if n==0 or n==1:
            return n 
            
        dp=[0]*(n+1)
        dp[0]=0
        dp[1]=1
        
        # fib数列下标从0开始,需要得到第n个项
        #数组下标也是从0开始,第n项为dp[n]
        for i in range(2,n+1):
            dp[i]=dp[i-1]+dp[i-2]
        return dp[n]%1000000007
	时间复杂度:O(n)
	空间复杂度:O(n)

维护两个数值就可以了,不需要记录整个序列。

class Solution:
    def fib(self, n: int) -> int:
        #动规是由前一个状态推导出来的
        if n==0 or n==1:
            return n
        dp=[0]*2
        dp[0]=0
        dp[1]=1
        for i in range(2,n+1):
            sum=dp[0]+dp[1]
            dp[0]=dp[1]
            dp[1]=sum
            
        return sum
	时间复杂度:O(n)
	空间复杂度:O(1)
class Solution:
    
    def fib(self, n: int) -> int:
        #  1.动态规划
        a,b=0,1
        sum=0
        
        #当n=0和1时,n-1为-1和0
        if n==0 or n==1:
            return n        

        #for循环运行第一次时,sum值为第3项值,a为第二项值,b为第三项
        #如果n=2,只需要输出一次,n=3,需要输出2次
        for _ in range(n-1):
            sum=a+b
            a=b
            b=sum
        return b%1000000007
class Solution:
    
    def fib(self, n: int) -> int:
        #  1.动态规划
        a,b=0,1
        sum=0
        for _ in range(n):
            sum=a+b
            a=b
            b=sum
        return a%1000000007

Python中 整型数字的大小 取决于计算机的内存(可理解为无限大)。不考虑整数越界问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【问题描述】 【问题描述】编函数f,功能是用递归的方法斐波那契数列的第n函数原型为 int f(int n),在主函数输入一个正整数n,调用函数f斐波那契数列的第n,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,21…… 【输入形式】3 【输出形式】2 【样例输入】6 【样例输出】8 【问题描述】编函数f,功能是用递归的方法斐波那契数列的第n函数原型为 int f(int n),在主函数输入一个正整数n,调用函数f斐波那契数列的第n,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,21…… 【输入形式】3 【输出形式】2 【样例输入】6 【样例输出】8 【问题描述】编函数f,功能是用递归的方法斐波那契数列的第n函数原型为 int f(int n),在主函数输入一个正整数n,调用函数f斐波那契数列的第n,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,21…… 【输入形式】3 【输出形式】2 【样例输入】6 【样例输出】8 【问题描述】编函数f,功能是用递归的方法斐波那契数列的第n函数原型为 int f(int n),在主函数输入一个正整数n,调用函数f斐波那契数列的第n,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,21…… 【输入形式】3 【输出形式】2 【样例输入】6 【样例输出】8 斐波那契数列:1,1,2,3,5,8,13,21…… 【输入形式】3 【输出形式】2 【样例输入】6 【样例输出】8
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值