算法学习-刷题

动态规划解题套路框架 :: labuladong的算法小抄 (gitee.io)今天学习这篇文章中的LeetCode509斐波那锲。

1、509斐波那锲

F[0] = 0, F[1] = 1, F(n) = F(n-1) + F(n-2)

方法1:暴力解法——递归

首先基线条件:F[0] = 0, F[1] = 1

循环条件:n>1

循环体:F(n) = F(n-1) + F(n-2)

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

 缺点是时间复杂度高,每次都要计算2个值,O(2^N),因为其中有很多重复运算,因此可以设置一个数组来存储之前计算得到的值。

方法2:有记忆的优化递归

注意在初始化数组的时候是*(n+1),因为n从0开始的,然后就是增加一个判断,如果这个值计算过则直接返回。

class Solution:
    def fib(self, n: int) -> int:
        #动态规划
        memo = [0]*(n+1)
        return self.mfib(memo, n)
    def mfib(self, memo, n):

        if n <= 1:
            memo[n] = n
            return memo[n]
            
        else:
            if memo[n] != 0:
                return memo[n]
            else:
                memo[n] = self.mfib(memo, n-1) + self.mfib(memo, n-2)
            return memo[n]

因为只每个值计算了一次,因此 算法复杂度O(N)。

方法3:动态规划

动态规划相当于创建一个记录表,与递归不同,从底向上实现,由循环迭代完成。蛮奇妙的,需要注意在设置基值时memo[1]的设定,当输入=0时会越界,所以N=0的情况需要单独判定。也是O(N)空间复杂度也是O(N)?

class Solution:
    def fib(self, n: int) -> int:
        #动态规划
        if n == 0:
            return 0
        else:
            memo = [0]*(n+1)
            memo[0] = 0
            memo[1] = 1
            if n <= 1:
                return memo[n]
            else:
                for i in range(2, n+1):
                    memo[i] = memo[i-1] + memo[i-2]
        return memo[n]

因为从通式来看,它之和两个状态有关,所以可以不用存储那么多的状态,可以进一步优化。

方法4:空间优化的动态规划

 空间复杂度为O(1)

class Solution:
    def fib(self, n: int) -> int:
        #动态规划
        if n <= 1:
            return n
        else:
            pre = 0
            cur = 1
            sum1 = 0
            for i in range(2, n+1):
                sum1 = pre + cur
                pre = cur
                cur = sum1
            return sum1

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值