代码随想录刷题39,40天|62.不同路径

62.不同路径

想要求dpij,只能有两个方向来推导出来,即dpi - 1j 和 dpij - 1

此时在回顾一下 dpi - 1j 表示啥,是从(0, 0)的位置到(i - 1, j)有几条路径,dpij - 1同理。

那么很自然,dpij = dpi - 1j + dpij - 1,因为dpij只有这两个方向过来。

python 复制代码
class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp=[[0]*n for _ in range(m)]#用来存储唯一路径数
        #设置第一行和第一列的基本情况
        for i in range(m):
            dp[i][0]=1
        for j in range(n):
            dp[0][j]=1
        #计算每个单元格的唯一路径数
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j]=dp[i-1][j]+dp[i][j-1]
            
        return dp[m-1][n-1]

63.不同路径2

其实只要考虑到,遇到障碍dpij保持0就可以了。

python 复制代码
class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        m=len(obstacleGrid)#行数
        n=len(obstacleGrid[0])
        if obstacleGrid[m-1][n-1]==1 or obstacleGrid[0][0]==1:#起点和终点有障碍物直接返回
            return 0
        dp=[[0]*n for _ in range(m)]
        for i in range(m):
            if obstacleGrid[i][0]==0:#遇到障碍物时,直接退出循环,后面默认都是0
                dp[i][0]=1
            else:
                break
        for j in range(n):
            if obstacleGrid[0][j]==0:
                dp[0][j]=1
            else:
                break
        for i in range(1,m):
            for j in range(1,n):
                if obstacleGrid[i][j]==1:
                    continue
                dp[i][j]=dp[i-1][j]+dp[i][j-1]
        return dp[m-1][n-1]

343.整数拆分

dpi:分拆数字i,可以得到的最大乘积为dpi

注意 枚举j的时候,是从1开始的。从0开始的话,那么让拆分一个数拆个0,求最大乘积就没有意义了。

至于 "拆分一个数n 使之乘积最大,那么一定是拆分成m个近似相同的子数相乘才是最大的"

python 复制代码
class Solution:
         # 假设对正整数 i 拆分出的第一个正整数是 j(1 <= j < i),则有以下两种方案:
        # 1) 将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j * (i-j)
        # 2) 将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j * dp[i-j]
    def integerBreak(self, n):
        dp = [0] * (n + 1)   # 创建一个大小为n+1的数组来存储计算结果
        dp[2] = 1  # 初始化dp[2]为1,因为当n=2时,只有一个切割方式1+1=2,乘积为1
       
        # 从3开始计算,直到n
        for i in range(3, n + 1):
            # 遍历所有可能的切割点
            for j in range(1, i // 2 + 1):

                # 计算切割点j和剩余部分(i-j)的乘积,并与之前的结果进行比较取较大值
                
                dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j)
        
        return dp[n]  # 返回最终的计算结果

96.不同的二叉搜索树

来看看n为3的时候,有哪几种情况。

当1为头结点的时候,其右子树有两个节点,看这两个节点的布局,是不是和 n 为2的时候两棵树的布局是一样的啊!

当3为头结点的时候,其左子树有两个节点,看这两个节点的布局,是不是和n为2的时候两棵树的布局也是一样的啊!

当2为头结点的时候,其左右子树都只有一个节点,布局是不是和n为1的时候只有一棵树的布局也是一样的啊!

dp3,就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量

元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量

元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量

元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量

所以递推公式:dpi += dpj - 1 * dpi - j; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量

左子树肯定时比根少一,右子树是要求的减去根,就是比他大的

python 复制代码
class Solution:
    def numTrees(self, n: int) -> int:
        dp=[0]*(n+1)
        dp[0]=1#当n为0时,只有一种情况
        for i in range(1,n+1):
            for j in range(1,i+1):
                dp[i]+=dp[j-1]*dp[i-j]#以j为头节点的左子树和以j为头节点的右子树
        return dp[n]
相关推荐
古城小栈11 小时前
为啥说:训练用BF16,推理用FP16
人工智能·算法·机器学习
KaMeidebaby11 小时前
卡梅德生物技术快报|蛋白 N 端测序在重组贻贝融合蛋白表征中的应用,解决原核表达序列偏移工艺难题
前端·人工智能·物联网·算法·百度
Turbo正则12 小时前
群论在AI中的应用概述
人工智能·算法·抽象代数
ysa05103012 小时前
【并查集】判环
c++·笔记·算法
Jerry12 小时前
KeetCode 44. 开发商购买土地
算法
Jerry12 小时前
KeetCode 58. 区间和
算法
Jerry13 小时前
LeetCode 209. 长度最小的子数组
算法
彦为君14 小时前
算法思维与经典智力题
java·前端·redis·算法
智能优化与强化学习14 小时前
Gym(Gymnasium)仿真环境详解(二):环境简介、入门算法、调参要点、核心挑战
算法·强化学习·gym·零基础入门·算法评估
mxwin14 小时前
Unity Shader exp 函数的算法与渲染应用
算法·unity·游戏引擎·shader