利用一维数组求菲波那契数列前40项的和并输出结果。_剑指 Offer 10 I. 斐波那契数列 leetcode 剑指offer系列...

题目难度: 简单

原题链接[1]

今天继续更新剑指 offer 系列, 这道题实在太经典了, 它也是动态规划的基础题目, 估计大家都见过, 今天就来复习一下吧~ 另外下面的做法还会有一些空间上的优化, 值得关注

若无意外, 每天晚上 6 点 45 分准时更新, 中间可能会穿插一些周赛题解. 大家在我的公众号"每日精选算法题"中的聊天框中回复 offer 就能看到该系列当前已经更新的文章了

大家有什么想法建议和反馈的话欢迎随时交流, 包括但不限于公众号聊天框/知乎私信评论等等~

题目描述

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

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

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

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

0 <= n <= 100

题目样例

示例 1

输入

n = 2

输出

1

示例 2

输入

n = 5

输出

5

题目思考

  1. 如何利用递推条件?

解决方案

思路

分析
  • 初始化条件和递推式(转移方程)都给了, 这就是最基础的动态规划思想了: 保存已有信息, 新的信息通过已有信息计算得到(就是转移过程), 避免重复计算
  • 这里引申一点, 动态规划的难点在于如何将具体问题进行转换, 以及如何找到转移方程
  • 我的建议是遇到问题都可以先尝试分析相邻的值(数组的相邻元素, 图的相邻点), 看看它们是否存在一些关系; 另外还可以尝试增加维度/状态找相邻点, 以及找当前值与之前多个值的关系等等
  • 感兴趣的小伙伴可以在我的公众号"每日精选算法题"中的聊天框中回复 股票, 那个系列里有几个比较进阶的动态规划题目
实现
  • 定义 dp 数组, 初始化dp[0] = 0, dp[1] = 1
  • 然后从 2 开始循环直到 n, 每次套用dp[n] = dp[n-1] + dp[n-2] 即可
  • 特别注意根据题目要求, 每次相加得到新的 dp 值时需要取模 (如果最后结果再取模的话, 对于 python 而言由于涉及大数操作, 速度会慢一些, 而对于 C/Java 等语言的话则可能会导致溢出)
  • 优化
    • 注意到当前 dp 值只和前面两个 dp 值有关, 所以我们完全可以只使用两个变量 preprepre, 分别代表当前下标的前一个和再上一个下标的 dp 值 dp[n-1]dp[n-2].
    • 然后当前的 dp 值就更新为它们两个的和
    • 最后更新当前 dp 值为新的 pre, 原来的 pre 就是新的 prepre
    • 而最终结果就是 pre 了, 因为遍历完 n 之后, 当前 dp 值已经更新为 pre

复杂度

  • 时间复杂度 O(N)
    • 需要遍历整个数组一遍
  • 空间复杂度 O(1)
    • 优化后只需要几个变量即可

代码

class Solution:
    def fib(self, n: int) -> int:
        if n 2:
            # n小于2的情况, 根据初始化, 直接返回n即可
            return n
        prepre, pre = 0, 1
        for i in range(2, n + 1):
            # 同时更新新的prepre和pre, 这里利用了python的语言特性, 同时赋值的时候不会相互影响, 其他语言可能需要额外一个tmp变量来先保存原来的pre了
            prepre, pre = pre, (prepre + pre) % 1000000007
        return pre

大家可以在下面这些地方找到我~?

我的知乎专栏[2]

我的 CSDN[3]

我的 Leetcode[4]

我的牛客网博客[5]

我的公众号: 每日精选算法题, 欢迎大家扫码关注~?

0ccf3fc9bbca175df38f1f22dc5100ef.png
每日精选算法题 - 微信扫一扫关注我

参考资料

[1]

原题链接: https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/

[2]

我的知乎专栏: https://zhuanlan.zhihu.com/c_1242508721932464128

[3]

我的 CSDN: https://me.csdn.net/zjulyx1993

[4]

我的 Leetcode: https://leetcode-cn.com/u/suibianfahui/

[5]

我的牛客网博客: https://blog.nowcoder.net/zjulyx

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值