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

343. 整数拆分

力扣

思路:动态规划

1. dp数组及其下标的含义:拆分数字i,可以得到的最大乘积为dp[i];

2. 递推公式:dp[i] = Math.max( dp[i], Math.max(j*(i-j), j*dp[i-j]));

    其中,j*(i-j) 代表拆分为 j 和 i-j,j*dp[i-j] 代表拆分为 j 以及和为 (i-j) 的若干个数;

    此外,需要通过 j 遍历所有存在的值,取其中最大的作为当前 i 的 dp[i];

3. dp初始化:dp[0] 和 dp[1] 从定义上来说不应该初始化;dp[2] = 1;

4. 遍历顺序:从前往后遍历i,范围 [3,n];从前往后遍历j,范围[1,i/2];

    其中,i 从3开始,dp[i-j] 就可以用得上初始化了的dp[2];

    j 遍历到 i/2:拆分一个数,一定是拆成 m 个近似相同的子数时乘积最大;m一定大于等于2,也就是说,最差拆成两个相同的子树;因此 j <= i/2;

class Solution {
    public int integerBreak(int n) {
        int[] dp = new int[n+1];
        dp[2] = 1;
        for(int i=3;i<=n;i++){
            for(int j=1;j<=i/2;j++){
                dp[i] = Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));
            }
        }
        return dp[n];
    }
}

思路:贪心算法

将正整数n进行有限次拆分为任意正整数,优先拆3,直到余数为4或2,此时子数乘积最大;

拆分正整数的最大乘积-数学证明

class Solution {
    public int integerBreak(int n) {
        if(n==2) return 1;
        if(n==3) return 2;
        if(n==4) return 4;
        int result = 1;
        while(n>4){
            result*=3;
            n-=3;
        }
        result*=n;
        return result;
    }
}

96.不同的二叉搜索树

力扣

思路:

1. 当n为1时候,有一棵二叉搜索树;当n为2时,有2棵二叉搜索树;

2. 当n为3时,共有5棵二叉搜索树:头节点为1时,右子树有2个节点,分布情况与n=2时的二叉搜索树的节点布局一致;头节点为2时,左右子树各有1个节点,分布情况与n=1时的二叉搜索树的节点布局一致;头节点为3时,左子树有2个节点,分布情况与n=2时的二叉搜索树的节点布局一致。递推关系:dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2];

96.不同的二叉搜索树2

3. dp数组及其下标含义:dp[i] 代表以1~i为节点组成的二叉搜索树的数量;

4. 递推关系:dp[i] += dp[j-1] * dp[i-j];j-1 代表以 j 为头节点时左子树的节点数量,i-j 代表以 j 为头节点时右子树的节点数量;j代表头节点元素,范围[1,i];

5. 初始化:dp[0] = 1;(空节点也是一棵二叉搜索树)

6. 遍历顺序:从前往后遍历i,范围[1,n];从前往后遍历j,范围[1,i];

class Solution {
    public int numTrees(int n) {
        int[] dp = new int[n+1];
        dp[0] = 1;
        for(int i=1;i<=n;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、付费专栏及课程。

余额充值