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

LeetCode343.整数拆分

题目链接:343.整数拆分

思路:

第一步:dp数组表示的是第n个整数的拆分后,获得最大的乘积值。

第二步:确定递推公式:对于从1遍历到 j 获得dp[i]的方式有两种:第一种通过 j * (i - j) 获得;第二种通过 j * dp[i - j] 方式获得。在这两种获得值得方式中取最大值。所以,dp数组得递推公式为
d p [ i ] = M a t h . m a x ( M a t h . m a x ( j ∗ ( i − j ) , j ∗ d p [ i − j ] ) , d p [ i ] ) dp[i] = Math.max(Math.max(j * (i - j), j * dp[i - j]), dp[i]) dp[i]=Math.max(Math.max(j(ij),jdp[ij]),dp[i])
第三步:初始化,由于使用不到 i == 0 和 i == 1 时得情况吗,所以直接从2开始进行初始化,dp[2] = 1。

第四步:遍历,对于递推公式dp[i] 的值需要使用dp[i - j] 的值,所以遍历需要从前向后进行。

代码:

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(Math.max(j * (i - j), j * dp[i - j]), dp[i]);
            }
        }
        return dp[n];
    }
}

LeetCode 96.不同的二叉搜索树

题目链接:96.不同的二叉搜索树

思路:

第一步:dp数组表示的是整数 n 个节点值从1到n互不相同的二叉搜索树的种类。

第二步:递推公式:通过对dp[3]的分析,dp[3] = 头节点为1时二叉搜索树的数量 + 头节点为2时二叉搜索树的数量 + 头节点为3时二叉搜索树的数量

头节点为1时二叉搜索树的数量 = 左子树有0个元素的二叉搜索树的数量 * 右子树有2个元素的二叉搜索树的数量

头节点为2时二叉搜索树的数量 = 左子树有1个元素的二叉搜索树的数量 * 右子树有1个元素的二叉搜索树的数量

头节点为3时二叉树搜索树的数量 = 左子树有2个元素的二叉搜索树的数量 * 右子树有1个元素的二叉搜索树的数量

所以,dp[3] = dp[0] * dp[2] + dp[1] * dp[1] + dp[2] * dp[0]。

所以,递推公式,dp[i] += dp[以j为头节点左子树] + dp[以j为头节点右子树],j相当于头节点元素,其从1遍历到i。
d p [ i ] + = d p [ j − 1 ] + d p [ i − j ] dp[i] += dp[j - 1] + dp[i - j] dp[i]+=dp[j1]+dp[ij]
第三步:初始化,只需要初始化dp[0] = 1,即可,右面的推导都是基于dp[0]推到出来的。

第四步:遍历顺序,采用两层遍历,首先是第一层遍历是遍历整个节点数,其次是遍历从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];
    }
}

你可能感兴趣的:(算法,leetcode,算法,动态规划)