- 343. 整数拆分
题目链接:. - 力扣(LeetCode)
刚看到这道题是没有思路的,看了卡哥的思路,这里其实有个规律,就是尽可能拆分出相同的数才会使乘积最大;这里定义 dp[i]是对 i 进行拆分,得到的最大乘积;
那么会有两种情况,一种是拆分两次即得到了最大乘积:i * (j-i), 一种是拆分三次及以上会得到最大乘积:及 j * dp[i - j] 这里不对 j 进行拆分是因为对 j 拆分的情况会在 dp[i-j]中已经包括了;除此之外,还要对比 dp [i]和前两者的大小,因为在每次拆分的时候,如果 dp [i]已经是最大则无需拆分
var integerBreak = function(n) {
let dp = new Array(n + 1).fill(0) //定义否则 Math.max可能为 NaN
dp[2] = 1
for(let i = 3; i <= n; i = i + 1) {
for(let j = 1; j < i - 1; j = j + 1) {
dp[i] = Math.max(j * (i - j), j * dp[i - j], dp[i])
}
}
return dp[n]
};
- 96.不同的二叉搜索树
题目链接:. - 力扣(LeetCode)
二叉搜索树定义
1. 若左节点不为空,则左子树上子节点值均小于根节点的值
2. 若右节点不为空,则右子树上子节点值均大于根节点的值
3. 左右子树也分别为二叉搜索树
这里需要探索递增的规律
对于 n = 3来说,以 1 和 3 为头节点的二叉树,子节点和 n=2的二叉树的形态一样,
对于n = 3的的二叉树的二叉树个数为 dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2], 对于二叉搜索树来说,
这里 d[i]为有 i 个节点时,二叉搜索树的个数
如果头节点为 j 的话,那么左子树节点个数为 j - 1 个,因为左子树上节点的数值都小于头节点,右子树的节点的个数为 i- j, 因为右子树的节点的数值都大于头节点,那递推公式即为 dp[j] = dp[j- 1] + dp[i - j]
初始化 dp[0] = 1, dp[1] = 1如果 dp[0]为 0 的话,乘积则还是 0
代码如下
var numTrees = function(n) {
let dp = new Array(n + 1).fill(0)
dp[0] = 1, dp[1] = 1
for(let i = 2; i <= n; i = i + 1) {
for(let j = 1; j <= i ; j = j + 1) {
dp[i] += dp[j-1] * dp[i -j]
}
}
return dp[n]
};