随想录训练营Day39 | DP - - 343. 整数拆分, 96.不同的二叉搜索树
标签: LeetCode闯关记
343. 整数拆分
confusion
- 完全想不到,dp和回溯 and 递归有什么关系?
- 难以理解两层for循环
- 为什么还要跟dp[i]本身比较一下 因为 i固定,j在遍历,我们要选一个最大的 dp[i]
class Solution {
public int integerBreak(int n) {
int[] dp = new int[n+1];//dp[i]表示将i拆分得到的最大积为dp[i];
dp[0] = 0;
dp[1] = 0;//当i为0||1时,其实并不能拆分,初始化没有意义
dp[2] = 1;//真正的初始化
//遍历顺序: 从前向后 ∵dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]
for (int i = 3; i <= n; i++) {//第一层for循环就是确定dp[3],dp[4],dp[5]...一直到dp[n]
for (int j = 1; j <= i - j; j++) { //第二层for循环是找dp[i]的具体过程
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));//dp[i]记录前面找出来的dp[i]的最大值; Math.max(j * (i - j), j * dp[i - j])确定当j = 某个数时,拆分i的最大积,j * (i - j)为拆成两个数;j * dp[i - j]为拆成>=3个数;
}//`j <= i - j;`因为,将i拆分成两个数,当j>i-j时,只是重复前面的结果. eg:i = 5, j = 2: j=i-j+1=4,那么i-j = 1;这种情况和j=1,i=4是相同的
}
return dp[n];
}
}
time: 1h30min
96.不同的二叉搜索树
Given an integer n, return the number of structurally unique BST's (binary search trees) which has exactly n nodes of unique values from 1 to n.
注意审题
structurally uniquemeans 结构不同
和
是结构相同的树
思路:
- dp数组含义:值为i的不同二叉搜索树有dp[i]种
- 递推公式:以j为头结点,左子树一定比j小,那么有j-1个结点,右子树一定比j大,有i-j个结点,且左右子树相乘关系, 再把所有以j为头结点的数量加起来,所以: dp[i] += dp[j-1] x dp[i-j]
- dp数组初始化:dp[0] = 1
- 遍历顺序:小到大 1<=i<=n 1<=j<=i
- 打印dp数组
class Solution {
public int numTrees(int n) {
int[] dp = new int[n+1];//dp[i]表示由i个节点组成的二叉搜索树有dp[i]种
dp[0] = 1;//dp[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];
}
}
time:1h
和
是结构相同的树