python动态规划图解_动态规划案例之python实现(一)

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2

输出: 2

解释: 有两种方法可以爬到楼顶。

1 阶 + 1 阶

2 阶

示例 2:

输入: 3

输出: 3

解释: 有三种方法可以爬到楼顶。

1 阶 + 1 阶 + 1 阶

1 阶 + 2 阶

2 阶 + 1 阶

原文章主要借由 2 个问题 来讲述什么是动态规划,由浅到深,本篇主要围绕第1个问题,使用python 实现(文中使用java实现)。

第2个问题放在下一篇实现。

# 针对试题一 的解法

# 最优解 斐波拉契数列

class Solution(object):

def climbStairs(self, n):

"""

:type n: int

:rtype: int

时间复杂度: O(2^n) ; 这是一颗二叉树,树的高度 n-1 ,节点有 2^(n-1)

空间复杂度: O(2^n) ; 因为每个计算结果都要存储,而且涉及重复计算

"""

assert isinstance(n,int),"n 不是整型,请确认后重新输入"

assert (n > 0), "n 必须大于0,请确认后重新输入"

if n <= 1:

return 1

elif n == 2:

return 2

return self.climbStairs(n-1)+self.climbStairs(n-2)

def climbStairs2(self, n, record=dict()):

"""

:type n: int

:rtype: int

备忘录算法,通过一个缓存,来减少重复计算

时间复杂度: O(n) ; f1~fn 除去 1,2 确定,其他都有走一遍,即 n-2

空间复杂度: O(n) ; 同理

"""

assert isinstance(n,int),"n 不是整型,请确认后重新输入"

assert (n > 0), "n 必须大于0,请确认后重新输入"

if n <= 1:

return 1

if n == 2:

return 2

if record.keys().__contains__(n):

return record.get(n)

else:

res = self.climbStairs2(n-1,record)+self.climbStairs2(n-2,record)

record[n]= res

return res

def climbStairs3(self, n):

"""

:type n: int

:rtype: int

减少空间复杂度,自底向上

时间复杂度: O(n) ; f1~fn 除去 1,2 确定,其他都有走一遍,即 n-2

空间复杂度: O(1) ; 因为每个计算结果都要存储两个变量

"""

assert isinstance(n,int),"n 不是整型,请确认后重新输入"

assert (n > 0), "n 必须大于0,请确认后重新输入"

if n == 1:

return 1

elif n == 2:

return 2

a,b,temp = (1,2,0)

for i in range(3,n+1):

temp = a+b

a = b

b = temp

return temp

if __name__ == ‘__main__‘:

s = Solution()

# res = s.climbStairs(4)

# res = s.climbStairs2(4)

res = s.climbStairs3(4)

print(res)

思路: climbStairs函数 是原始解法,但时间及空间复杂度均很大 O(2^n), 考虑到有重复计算,

所以加个缓存备忘录 字典record, 没有的加进去,后续再遇到就直接从record中取值,没必要再递归到最底层得到结果。即 climbStairs2 函数

再进一步考虑优化 空间复杂度,自底向上,每次只保留最近的两个结果,即 climbStairs3 函数

原文:https://www.cnblogs.com/jason-Gan/p/13303601.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值