代码随想录第三十四天(动态规划)| 整数拆分|不同的二叉搜索树

整数拆分

五部曲,拆分整数,给定一个整数n,第一个数从1开始拆,会剩下n-1,于是从这里可看出,n-1又可以继续分为1和n-1.现有的状态依赖之前的状态,于是可以看出dp数组的定义了。计算完1之后,递增从2又开始拆。直到递增到n

  1. dp[i]代表的是将一个整数i拆分成k个整数的最大乘积值dp[i]。
  2. 递推公式:dp[i]=max(j*(i-j),j*dp[i-j],dp[i])。这里j代表的就是上面的从j开始拆,这里分了两种情况,一种是k为2的情况,两个数直接相乘即可,然后就是k大于2的情况。然后固定i值,以j为起点拆,j不同又会有很多种不同的结果,这里要取i等于某一个值时的最大dp[i]值
  3. 初始化:dp[0]=0,dp[1]=0,dp[2]=1,因为根据上面的递推公式,i=3时才能拆分多种情况,才能使用递推公式。
  4. 从小到大遍历
class Solution {
    public int integerBreak(int n) {
        int[] dp=new int[n+1];
        dp[0]=0;
        dp[1]=0;
        dp[2]=1;
        for(int i=3;i<n+1;i++){
            for(int j=1;j<=i/2;j++){//对i进行拆分,求dp[i]
                //这里要取dp[i]的最大值
                dp[i]=Math.max(Math.max((j*(i-j)),j*dp[i-j]),dp[i]);
            }
        }
        return dp[n];
    }
}

不同的二叉搜索树

这一题可以看出,选择不同的头结点,其左右子数就是之前经历过的状态。这里没有想到是dp[左子树]*dp[右子树]。只发现了当前状态可以拆分成之前的状态

  1. dp[i]代表的是由i个节点组成的互不相同的二叉搜索树的数量值为dp[i]
  2. 递推公式:先选择一个头结点为j,j从1开始遍历直到i;dp[i]+=dp[j-1]dp[i-j]
  3. 初始化:dp[0]=0,因为dp[1]可以由递推公式推出了
  4. 遍历顺序,i从小到大遍历
class Solution {
    public int numTrees(int n) {
        int[] dp=new int[n+1];
        dp[0]=1;
        for(int i=1;i<n+1;i++){
            for(int j=1;j<=i;j++){
                dp[i]+=dp[j-1]*dp[i-j];
            }
        }
        return dp[n];
    }
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值