动态规划03 | ● *343. 整数拆分 ● *96.不同的二叉搜索树

*343. 整数拆分

https://programmercarl.com/0343.%E6%95%B4%E6%95%B0%E6%8B%86%E5%88%86.html
视频讲解:https://www.bilibili.com/video/BV1Mg411q7YJ

  • 考点
    • 动态规划
  • 我的思路
    • 无思路
  • 视频讲解关键点总结
    • 怎么想到动态规划的?一个数可以拆成两个数,也可以拆成多个数;如果拆成多个数,相当于先拆出来的两个数中有一个应该继续拆下去,这时候就可以用到动态规划了,因为那个继续拆的数字能拆出来的最大乘积可以通过dp数组的遍历在之前得到
    • 动规五部曲
      • dp数组的每个位置 i 对应数字 i 经拆分后能得到的最大乘积
      • 递推公式,取以下三种情况里的最大值作为当前dp值
        • 把当前数拆成两个数字的乘积
        • 把当前数拆成多个数字的乘积(初始拆成两个数,选其中一个数取其dp值,即相当于对其进行了进一步拆分并获取到最大乘积)
        • 当前dp值
      • 初始化
        • dp[0]和dp[1]其实不能拆分,所以初始化为0
        • dp[2]可拆分,初始化为1
        • 之后从dp[3]开始使用动态规划递推
      • 从前向后遍历,双层for循环,外层负责遍历dp,内层负责遍历当前 i 拆成两个数的所有情况
      • 不需要打印
  • 我的思路的问题
    • 无思路
  • 代码书写问题
  • 可执行代码
class Solution:
    def integerBreak(self, n: int) -> int:
        dp = [0] * (n + 1)
        dp[2] = 1
        for i in range(3, n + 1):
            for j in range(1, i):
                dp[i] = max(j * (i - j), j * dp[i - j], dp[i])
        return dp[-1]

*96.不同的二叉搜索树

https://programmercarl.com/0096.%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html
视屏讲解:https://www.bilibili.com/video/BV1eK411o7QA

  • 考点
    • 动态规划
  • 我的思路
    • 无思路
  • 视频讲解关键点总结
    • 二叉树的题还是要画图分析!!
    • 以n为3为例进行分析,所有的二叉搜索树结果分为以1为根节点、2为根节点和3为根节点的情况
      • 1为根节点,左子树只有1种情况,即空树,右子树有2/3两个子节点,组合为两种情况
      • 2为根节点,左子树有一种情况1,右子树有一种情况3
      • 3为根节点,左子树有1/2两个子节点,组合为两种情况,右子树有一种情况即空树
    • 分析可发现,由于二叉搜索树的性质,其左子树和右子树的情况可以通过比n小的情况时的二叉搜索树数量递推得到
    • dp数组第 i 个元素代表n为 i 的时候共有多少种可能的二叉搜索树
    • 递推公式为,循环遍历从1为根节点到n为根节点的情况,并对遍历到 j 时,令dp[n] += dp[j - 1] * dp[n - j] (这里右子树直接去n-j对应的dp值,是因为树有多少种可能的结构与递增数组的具体值无关,只与其数的个数有关,因此可以如此操作)
    • 将dp[0]初始化为1,代表空树的情况共有一种
    • 双重循环,均从前向后遍历
    • 无需打印
  • 我的思路的问题
    • 无思路
  • 代码书写问题
  • 可执行代码
class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0] * (n + 1)
        dp[0] = 1
        for i in range(1, n + 1):
            for j in range(1, i + 1):
                dp[i] += dp[j - 1] * dp[i - j]
        return dp[n]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值