首页 > 编程语言 > 详细

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

时间:2020-07-15 11:28:36      阅读:48      评论:0      收藏:0      [点我收藏+]

本文参考文章:
《漫画:什么是动态规划?(整合版)》 https://mp.weixin.qq.com/s/3h9iqU4rdH3EIy5m6AzXsg

题1: 爬楼梯: https://leetcode-cn.com/problems/climbing-stairs/

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶
    示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 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 函数

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

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!