题目一 343. 整数拆分
思路
-
确定含义:dp[i]是指拆分数字i,可以得到的最大乘积dp[i]
-
递推公式
-
dp[i] = max((i-j)*j, dp[i-j]*j)- j * (j-j)直接相乘
- j * dp[i-j]相当于拆分i-j, 包含3个数相乘,4个数相乘,... i-j个数相乘
-
dp初始化:dp[2] = 1
-
遍历顺序:从前向后
这个递归公式想不到。。。不是很懂
var integerBreak = function(n) {
const dp = new Array(n+1).fill(0);
dp[2] = 1;
for (let i = 3; i <= n; i++) {
for (let j = 1; j < i; j++) {
dp[i] = Math.max(dp[i], Math.max((i-j)*j, dp[i-j]*j))
}
}
return dp[n];
};
题目二 96. 不同的二叉搜索树
思路
- dp[i]: i个节点构造不同二叉搜索树的个数
- 递推公式:
dp[i] += dp[j - 1] * dp[i - j],代表分别以1到j为头节点构造的二叉搜索树的和。那以j为头结点的二叉树,左边有j-1个节点,值就是dp[j - 1], 右边有i-j个节点,就是dp[i-j],所以依次把所有能构造出来的子树的和求出来就是dp[i]的结果 - 初始值:dp[0] = dp[1] = 1;
- 循环顺序,因为递推公式是依据前面的值计算出来的,所以是从前向后遍历,从2开始计算,内层循环j从1到i(包含i),依次求和
var numTrees = function(n) {
// 比n大一的数组
const dp = new Array(n + 1).fill(0);
dp[0] = 1;
dp[1] = 1;
for (let i = 2; i <= n; i++) {
for (let j = 1; j <= i; j++) {
dp[i] += dp[j-1]* dp[i-j];
}
}
return dp[n];
};