leetcode 509. 斐波那契数 python 剑指offer 1

leetcode 509 斐波那契数

题目描述

在这里插入图片描述

解法

最开始想,这道题肯定用递归啊

class Solution:
    def fib(self, n: int) -> int:
        if n < 0:
            return None
        if n == 0:
            return 0
        if n == 1:
            return 1
        return self.fib(n-1) + self.fib(n-2)

但是不是这么简单的,这样会超时!!很多f(n)会被重复计算。所以来找一找规律。
在这里插入图片描述
f(n)其实只与f(n-1), f(n-2)有关,所以我们就考虑用a和b记录这两个值。
最开始的时候,n=0,a=0;n=1,b=1(红色标记),通过a+b就能得到f2=1。那么现在就是有a=f0,b=f1,f2。
这时我们要计算f3,实际上只需要f1和f2,f0可以抛弃了。所以将a变为f1,b变为f2(黄色标记)。
依次类推,不断更新a和b,得到最终的结果,这过程中,也并没有重复的计算导致时间复杂度变高。

那么,如何实现这个过程呢?
就可以考虑用for循环,俗话说万丈高楼平地起。我们就从0和1建起,建到n。

先看要循环几次?
我们看图,当算f2时,要更新一次ab(红);f3时,要更新2次ab(红黄);f4时,要更新3次ab(红黄蓝)

f6时,更新了5次ab
所以循环的次数就是n-1,所以就是for i in range(n-1).

次数确定后,在for要写什么呢?
那就是更新ab啦!
看图可知,新一轮的a是等于旧一轮的b,新一轮的b是等于旧一轮a+b的结果。
好,上代码!

class Solution:
    def fib(self, n: int) -> int:
        if n < 0:
            return None
        if n == 0:
            return 0
        if n == 1:
            return 1
        a,b = 0,1
        for i in range(n-1):
            # 当前得数
            num = a+b
            # 更新ab
            a = b
            b = num
        return num

通过!!循环了n-1次,所以时间复杂度为O(n)。

注意:
在 剑指offer 系列中,多加了个要求
在这里插入图片描述
我说这方法这么完美,怎么会出错呢???
那么就最后return的地方修改一下就好了!
在这里插入图片描述
总结:
递归的思路很简单,但是时间复杂度高,很多重复计算。
刚开始,其实是考虑用哈希表存储fn的值,但是n很大的时候,需要的空间也很大,这就是用空间换取时间。
最终的方法,时间空间都很nice,主要还是要学会找规律,不会找怎么办?看答案,理解答案,记住答案。

发布了28 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/xxx_gt/article/details/104947861