斐波那契数列 509 一步一步优化

文章介绍了如何从暴力递归解决斐波那契数列问题出发,通过使用备忘录减少重复计算,将时间复杂度从O(2^n)优化到O(n),再进一步利用状态压缩将空间复杂度降低到O(1)。
摘要由CSDN通过智能技术生成

力扣斐波那契数列 509

虽然这是一道简单题,但是对于我这个新手来说,有很多可以学习的算法改进的思路。拿到这个题的时候,第一想法就是暴力递归。
#暴力递归
def fib(self, n: int) -> int:
       if n==0:
           return 0
       elif n==1:
           return 1
       else:
           return self.fib(n-1)+self.fib(n-2)

但是。。。
暴力递归算法会重复计算很多步骤,按照递归算法时间复杂度的算法=子问题的个数*子问题所占用的时间 那么暴力递归算法时间复杂度为O(2^n)。例如:


在这里插入图片描述
蓝色虚框内的算法都会重复一遍。然后我就看了大家的题解,主要是从这篇题解中学习的:参考题解
因此要对暴力递归算法进行改进,把部分重复的值用字典存起来,用的时候调用,就会减少重复计算的步骤。这种字典或者解决问题的方式叫做备忘录。
备忘录的递归算法(只写核心部分)–严格意义上,这已经不是递归了,没有对自己函数的调用,应该是递推:

dic={0:0,1:1}
for i in range(2,n+1):
    dic[i]=dic[i-1]+dic[i-2]
return dic[n]

时间复杂度为O(n)。但是这样,还是存在一个问题,因为我们要求解的值f(n),显然只和f(n-1)和f(n-2)有关,那么其他的更小项对应的值只会用到一次,占据了空间。
所以,最好在用完之后就delete掉,这样的话,空间复杂度就可以得到优化,这个过程叫做状态压缩。
状态压缩的dp算法:

            m=0
            p=0
            q=1
            for i in range(3,n+1):
                p=q
                q=p+m
                m=p
            return p+q

状态压缩之后空间复杂度变为O(1)。结束。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值