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

343. 整数拆分

本题就是一个个递推,通过将dp[i]定义为第i个值的最大乘积
然后最大乘积有两种来源,一个是(i - j) * j 还有一种是dp[i - j] * j;

  • 解题思路:
    1.确定dp数组(dp table)以及下标的含义。dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。
    2.确定递推公式dp[i] = Math.max(dp[i], Math.max((i - j) * j, dp[i - j] * j));//这里不断更新dp[i]的值
    3.只初始化dp[2] = 1,从dp[i]的定义来说,拆分数字2,得到的最大乘积是1
    4.dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]

  • 推导过程

    Snipaste_2023-04-24_20-42-34

public int integerBreak(int n) {
    //dp[i]表示i的最大乘积
    int[] dp = new int[n + 1];

    //初始化2的最大乘积为1
    dp[2] = 1;

    for (int i = 3; i <= n; i++) {

        for (int j = 1; j < i; j++) {
            dp[i] = Math.max(dp[i], Math.max((i - j) * j, dp[i - j] * j));
        }

    }

    return dp[n];
}

96.不同的二叉搜索树⭐️

重点在于递推公式的推导以及利用二叉搜索树已经排好序的性质解题

  • 递推公式推导

    Snipaste_2023-04-24_21-01-57

  • 解题思路:
    1.dp[i] : 1到i为节点组成的二叉搜索树的个数为dp[i]
    2.递推公式:dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量
    3.初始化:从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,因此初始化dp[0] = 1
    4.遍历顺序:首先一定是遍历节点数,从递归公式:dp[i] += dp[j - 1] * dp[i - j]可以看出,节点数为i的状态是依靠 i之前节点数的状态。

  • 推导过程

    image-20230424212146645

public int numTrees(int n) {
    int[] dp = new int[n + 1];

    //初始化
    dp[0] = 1;
    for(int i = 1;i <= n;i++){
        //j用来确定不同的i不同的情况
        //j变量即以j作为头结点的求i的情况,每一次循环都是加上不同的情况
        for(int j = 1;j <= i;j++){
            dp[i] += dp[j - 1] * dp[i - j];
        }
    }

    return dp[n];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值