文档讲解:343. 整数拆分、96.不同的二叉搜索树
题目链接:343. 整数拆分、96.不同的二叉搜索树
思路:
1、整数拆分这个题最难的一步就是递推公式,其实可以从1遍历j,然后有两种渠道得到dp[i]。一个是j * (i - j) 直接相乘。一个是j * dp[i - j],相当于是拆分(i - j),对这个拆分不理解的话,可以回想dp数组的定义。所以递推公式:dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});
2、二叉搜索树的性质就是,如果左子树不为空,左子树的所有节点值都比根节点小,如果右子树不为空,右子树的所有节点值都比根节点大。dp[i]就是当n为i时,有多少种树。如当i等于3时,有三种方案,第一种是根节点为1,则有两种书,根右右,跟右左。当根节点为2时,有一种方案,213,当根节点为3时,有2种方案,根左右,跟左左。所以可以得出递推公式:dp[i] += dp[j-1]*dp[i-j]。
343. 整数拆分
class Solution {
public int integerBreak(int n) {
//dp[i]代表正整数i的最大乘积
//dp[i] = Max(dp[i-j]*dp[j]);
int[] dp = new int[n+1];
dp[2] = 1;
for(int i=3;i<=n;i++){
for(int j=1;j<=i-j;j++){
dp[i] = Math.max(Math.max(j*(i-j), j*dp[i-j]),dp[i]);
}
}
return dp[n];
}
}
96.不同的二叉搜索树
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];
}
}