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

目录

343. 整数拆分

96.不同的二叉搜索树


343. 整数拆分

代码随想录

视频讲解:动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分_哔哩哔哩_bilibili

题解思路:

题目还是动态规划的常规题目,使用n+1数组保存0-n范围内正整数拆分后的最大值,这里最大值的取法需要注意,要考虑三种情况:
1、拆成两个数的情况:12 , 21
2、拆成三个数(dp[i]至少会拆分成两个数)及以上的情况:dp[3]就是看dp[2]*1、dp[1]*2 ,dp[4]就是看dp[3]*1、dp[2]*2、dp[1]*3
3、还有就是要保持dp[3]要最大,只有拆分比当前dp[3]大的时候,此时才更新dp[3]

class Solution {
    public int integerBreak(int n) {
        //动规第一步:确定dp[i]的含义:整数i拆分后得到的乘积最大值
        //动规第二步:确定递推公式:这里其实还是依赖上一个数拆分后取得的最大值,比如dp[3]最大值就是看
            //拆成两个数的情况:1*2 , 2*1
            //拆成三个数(dp[i]至少会拆分成两个数)及以上的情况:dp[3]就是看dp[2]*1、dp[1]*2 ,dp[4]就是看dp[3]*1、dp[2]*2、dp[1]*3
            //还有就是要保持dp[3]要最大,只有拆分比当前dp[3]大的时候,此时才更新dp[3]
            //综合上述三点其递推公式为:dp[i] = Math.max{ (i - j)*j, dp[i-j]*j, dp[i]}
        //动规第三步:初始化dp数组:dp[1] = 0 dp[2] = 1
        //动规第四步:确定遍历顺序:从前往后遍历
        //动规第五步:打印dp数组
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 0;
        dp[2] = 1;
        for(int i = 3; i < dp.length; i++){
            for(int j = 1; j < i; j++){
                dp[i] = Math.max(Math.max((i - j)*j, dp[i-j]*j), dp[i]); //Math.max(a,b)只能两者比较取其一
            }
        }
        return dp[dp.length-1];
    }
}

96.不同的二叉搜索树

代码随想录

视频讲解:动态规划找到子状态之间的关系很重要!| LeetCode:96.不同的二叉搜索树_哔哩哔哩_bilibili

题解思路:

依然是动态规划的常规题,跟着卡哥按部就班刷下来确实有点感觉了,想知道输入n后,即有n个节点一共有多少种不同二叉搜素树的个数,还是得依赖于有n-1个节点时构成的二叉搜索树的个数,但是需要考虑左右子树在不同的节点个数情况下的排列组合,具体说明见代码注释!!!

class Solution {
    public int numTrees(int n) {
        //确定dp[i]的含义:输入i,也就是i个节点组成二叉搜索树的种树
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;
        if(n > 1) dp[2] = 2;
        for(int i = 3; i < n + 1; i++){ //控制dp数组的下标dp[i]
            for(int j = 1; j <= i; j++){  //控制头节点的值,根据二叉搜索树的特性,左子树的值 < 根节点的值 < 右子树的值,则根节点的值-1 = 左子树的节点个数, i-根节点的值 = 右子树的节点个数
                dp[i] += dp[j - 1] * dp[i - j]; //dp[i-1]:就是左子树有i-1个节点时,总共有dp[i-1]种不同的二叉树
                                                //dp[i -j]:就是右子树有j-i个节点时,总共有dp[i-j]种不同的二叉树
                                                //对左右二叉树的个数排列组合就是相乘得到总的
            }
        }
        return dp[n];
    }
}

你可能感兴趣的:(数据结构与算法,算法,leetcode,数据结构)