代码随想录算法训练营第41天| 343. 整数拆分、96. 不同的二叉搜索树

文章介绍了如何使用动态规划方法解决两个经典问题:整数拆分,通过最大化乘积来拆分整数;以及构建不同的二叉搜索树,计算特定数量节点的二叉搜索树的组合。关键在于定义状态和状态转移方程,通过迭代更新找到最优解。
摘要由CSDN通过智能技术生成

343. 整数拆分:


代码思路
dp[i]就是答案(定义状态)。状态转移方程是max(i * (k-i), dp[i] * (k-i))。就是分成两种情况,第一种就是两个数相乘,第二种就是超过两个数相乘的情况。i * (k-i)是两个数相乘,dp[i] * (k-i)是超过两个数相乘的情况。但是重点还是先固定一个数,后面还有逐个逐个根据不同固定的数来比较一下。思路比较绕。

class Solution:
    def integerBreak(self, n: int) -> int:
        dp = [-1 for i in range(n+1)]
        dp[0] = dp[1] = 0
        k = 2
        while k <= n:
            for i in range(k):
                temp = max(i * (k-i), dp[i] * (k-i))
                if temp > dp[k]:
                    dp[k] = temp
            k += 1
        return dp[-1]

96. 不同的二叉搜索树:


代码思路
(首先是dp[i]即答案。
然后要懂得分解子问题,
基本状态转移方程就好推了。)
dp[i]即答案(定义状态),也就是i个节点构成的搜索树数量,倒推状态转移!倒推出来就差不多了。这题状态转移的发现要比较细心。其实就是分别拿一个节点作为根节点,左节点为子问题,右节点为子问题,左和右排列组合数相乘就ok了。所以说树类型的动态规划就是左子树和右子树变成了子问题,是不是以后碰到树+动归就好推了?其实动归就是递归中少了递的过程,只有归!!

class Solution:
    def numTrees(self, n: int) -> int:
        if n == 1:
            return 1
        dp = [0 for i in range(n+1)]  # 代表由k个节点(数)组成的二叉搜索树数量
        # for i in range(len(n)): # 轮流来作为根节点
        i = 2
        dp[1] = 1
        while i <= n:
            for j in range(1, i+1):
                # j位置为根节点,dp[左边的节点个数]+dp[右边的节点个数]
                if dp[j-1] == 0:
                    dp[i] += dp[i-j]
                elif dp[i-j] == 0:
                    dp[i] += dp[j-1]
                else:
                    dp[i] += dp[j-1]*dp[i-j]
            i += 1
        return dp[n]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值