首页 > 其他分享 >代码随想录|动态规划

代码随想录|动态规划

时间:2023-06-25 19:34:41浏览次数:32  
标签:obstacleGrid return int 代码 随想录 range 动态 self dp

 理论基础 

509. 斐波那契数 

70. 爬楼梯 

746. 使用最小花费爬楼梯 

62.不同路径 

63. 不同路径 II 

343. 整数拆分 

96.不同的二叉搜索树


动态规划理论基础

动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。

所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的

对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

509. 斐波那契数

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

 


70. 爬楼梯

记住要由递归公式推导出dp公式

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 1:
            return 1
        if n == 2:
            return 2
        dp = [0 for _ in range(n+1)]
        dp[1] = 1
        dp[2] = 2
        for i in range(3, n+1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]

746. 使用最小花费爬楼梯

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        if n == 1:
            return 0
        if n == 2:
            return min(cost[0], cost[1])
        dp = [0 for _ in range(n)]
        dp[0] = cost[0]
        dp[1] = cost[1]
        for i in range(2, n):
            dp[i] = cost[i] + min(dp[i-1], dp[i-2])
        return min(dp[-1], dp[-2])
        

 


62.不同路径

class Solution:
    def uniquePaths(self, m: int, n: int) -> int: #M行 N列
        if m == 1 or n == 1:
            return 1
        dp = [[0 for _ in range(n)] for _ in range(m)]
        for i in range(n):
            dp[0][i] = 1
        for j in range(m):
            dp[j][0] = 1
        for j in range(1, m):
            for i in range(1,n):
                dp[j][i] = dp[j-1][i] + dp[j][i-1]
        return dp[-1][-1]

 


63. 不同路径 II

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        n = len(obstacleGrid) #N行M列
        m = len(obstacleGrid[0])
        dp = [[0 for _ in range(m)]for _ in range(n)]
        if obstacleGrid[0][0] == 1:
            dp[0][0] = 0
        else:
            dp[0][0] = 1
        for i in range(1, m):
            if obstacleGrid[0][i] == 1:
                dp[0][i] = 0
            else:
                dp[0][i] = dp[0][i-1]
        for j in range(1, n):
            if obstacleGrid[j][0] == 1:
                dp[j][0] = 0
            else:
                dp[j][0] = dp[j-1][0]
        for j in range(1, n):
            for i in range(1, m):
                if obstacleGrid[j][i] == 1:
                    dp[j][i] = 0
                else:
                    dp[j][i] = dp[j-1][i] + dp[j][i-1]
        return dp[-1][-1]

 


343. 整数拆分

注意遍历所有切割点的时候只用遍历【0,i//2+1】

class Solution:
    def integerBreak(self, n):
        if n <= 3:
            return 1 * (n - 1)  # 对于n小于等于3的情况,返回1 * (n - 1)

        dp = [0] * (n + 1)  # 创建一个大小为n+1的数组来存储最大乘积结果
        dp[1] = 1  # 当n等于1时,最大乘积为1
        dp[2] = 2  # 当n等于2时,最大乘积为2
        dp[3] = 3  # 当n等于3时,最大乘积为3

        # 从4开始计算,直到n
        for i in range(4, n + 1):
            # 遍历所有可能的切割点
            for j in range(1, i // 2 + 1):
                # 计算切割点j和剩余部分(i - j)的乘积,并与之前的结果进行比较取较大值
                dp[i] = max(dp[i], dp[i - j] * dp[j])

        return dp[n]  # 返回整数拆分的最大乘积结果

96.不同的二叉搜索树

相乘的思想

class Solution:
    def numTrees(self, n: int) -> int:
        if n == 1:
            return 1
        dp = [0 for _ in range(n+1)]
        dp[0] = 1
        dp[1] = 1
        for i in range(2, n+1):
            for j in range(0,n):
                dp[i] += dp[j]*dp[i-j-1]
        return dp[n]   

 

标签:obstacleGrid,return,int,代码,随想录,range,动态,self,dp
From: https://www.cnblogs.com/fangleSea/p/17503773.html

相关文章

  • 用coredns加etcd,搭建跨平台动态服务发现
    corednsddns服务发现动态 servicediscovery2023-0625第一版---【前言】---coredns被我喜爱的原因:跨平台,支持win,linux版同时使用。同时支持配置文件和etcd。我用它来搭建动态服务发现。coredns下载:内含win,linux版https://github.com/coredns/coredns/releases相关下载:ht......
  • 作为初级开发人员如何进行代码审查?
    “代码必须经过高级开发人员的审查。” “后辈的评论很好,但他们的认可毫无价值。” 如果您从未听过这些,那么您很幸运。当然,他们完全错了。作为初级开发人员,参与代码审查提供了宝贵的学习机会以及为团队的成功做出贡献的机会。在这篇文章中,我将探讨如何作为初级开发人员提供有效的......
  • 代码审计——垂直越权详解
    01漏洞描述垂直越权,也称权限提升,是一种“基于URL的访问控制”设计缺陷引起的漏洞。由于Web应用程序没有做权限控制或者仅在菜单上做了权限控制,导致的恶意用户只要猜测其他管理页面的URL,就可以访问或控制其他角色拥有的数据或页面,达到权限提升目的。02审计要点垂直越权漏洞发生......
  • 代码审计——任意文件下载详解
    01漏洞描述网站可能提供文件查看或下载的功能,如果对用户查看或下载的文件不做限制,就能够查看或下载任意的文件,可以是源文件,敏感文件等等。02审计要点任意文件下载漏洞发生的根本原因是系统自带的查看或下载功能,用户可控制下载路径,且当服务器不做任何限制的时候,就可以完成对任意文......
  • 代码审计——目录遍历详解
    01漏洞描述目录遍历,即利用路径回溯符“../”跳出程序本身的限制目录实现下载任意文件。例如Web应用源码目录、Web应用配置文件、敏感的系统文(/etc/passwd、/etc/paswd)等。一个正常的Web功能请求为http://www.test.com/lownload.php?file=test.php。如果Web应用存在路径遍历漏洞,则......
  • 代码审计——未授权访问详解
    01漏洞描述未授权访问漏洞,是在入侵者没有获取到登录权限或未授权的情况下,或者不需要输入密码,即可通过直接输入网站控制台主页面地址,或者不允许查看的链接便可进行访问,同时进行操作。简单来说,就是用户不经过身份认证即可访问敏感资源,可能造成敏感信息泄露,或者其他恶意操作。02审计......
  • 代码审计——SSRF详解
    01漏洞描述服务端请求伪造(SSRF)也成为跨站点端口入侵,是由于一些应用在向第三方主机请求资源时提供了URL并通过传递的URL来获取资源引起的,当这种功能没有对协议、网络可信便捷做好限制时,入侵者可利用这种缺陷来获取内网敏感数据、DOS内网服务器、读文件甚至于可获取内网服务器控制......
  • 代码审计——命令执行详解
    01漏洞描述命令注入是指因为系统使用了可以执行命令的危险函数,但是调用这些函数的参数可控,并没有做过滤或过滤不严格,使入侵者可以通过构造特殊命令字符串的方式将数据提交至Web应用程序中,并利用该方式执行外部程序或系统命令实施入侵,来非法获取数据或者网络资源。简单来说,就是......
  • 代码审计——XXE详解
    01漏洞描述XXE(XMLExternalEntityInjection)是一种针对XML终端实施的入侵,漏洞产生的根本原因就是在XML1.0标准中引入了“entity”这个概念,且“entity”可以在预定义的文档中进行调用,XXE漏洞的利用就是通过实体的标识符访问本地或者远程内容。黑客想要实施这种入侵,需要在XML的payl......
  • 代码审计——XSS详解
    01漏洞描述跨站脚本入侵(CrossSiteScript)是一种将恶意JavaScript代码插入到其他Web用户页面里执行以达到入侵目的的漏洞。入侵者利用应用程序的动态展示数据功能,在html页面里嵌入恶意代码。当用户浏览该页之时,这些嵌入在html中的恶意代码会被执行,用户浏览器被入侵者控制,从而达到......