所用代码 java
整数拆分 LeetCode 343
题目链接:整数拆分 LeetCode 343 - 中等
思路
无。
尽可能拆成m个近似相同的数,乘积才是最大。
- dp数组含义:整数i拆分之后最大的乘积为dp[i]
- 递推公式: 2个数:j x (i - j) => 3个及以上:j x dp[i-j]
- 初始化:dp[0] = 0, dp[1] = 0, dp[2] = 1
- 遍历方向:左到右 3<=n 1<j<i
- 打印
class Solution {
public int integerBreak(int n) {
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 0;
dp[2] = 1;
// dp数组从i=3开始
for (int i = 3; i <= n; i++) {
// 数为n可以拆分的情况
for (int j = 1; j < i; j++) {
// 比较拆分成两个数大,还是拆分成3及以上的数大,或是拆分之后有没有原来的数大
dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
}
}
return dp[n];
}
}
总结
本题的难点在于dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
我们在拆分数字的时候,只需要固定一个数j,然后对另一个数进行拆分,然后每次把乘积最大值进行返回,再把固定的数j乘进去就是最大值了。但是我们拆分的情况有i-j种,所以每次得到的最优结果还要保存比较下一次的值,取最优的结果。
此外本题还可以进行优化,对于拆分的次数,只需要令 j <= i/2
就行了,因为对于某个人拆分一半之后,后面的都是一样的数。
另外本题还可以使用贪心思路(有数学证明):我们把n拆分成m个3的乘积是最大的
不同的二叉搜索树 LeetCode 97
题目链接:不同的二叉搜索树 LeetCode 97 - 中等
思路
无。
n=3时,有头结点为1、头结点为2、头结点为3三种情况:
头结点为1 = 左子树0个节点 x 右子树2个节点
头2 = 左 1 x 右 1
头3 = 左2 x 右 1
- 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, dp[1] =1
- 遍历顺序:小到大 1<i<=n 1<j<=i
- 打印dp数组
class Solution {
public int numTrees(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
// 从根结点1到i一个一个的遍历
for (int j = 1; j <= i; j++) {
// 每个结点的数量都要加上 左子树数量乘右子树数量
dp[i] += dp[j-1] * dp[i-j];
}
}
return dp[n];
}
}
总结
本题主要是要想到我们的根结点的值可以是 1-i 的每一个值,我们需要加上这些以j为根结点的数量,其次以j为根结点的数量是左子树的所有情况 乘 右子树的所有情况。