LeetCode:343. 整数拆分 - 力扣(LeetCode)
1.思路
理一下思路:可以用边界排除法做,见代码实现,略。利用动规,将数拆分为多个近似相等的数,一层for循环用来遍历前面每一个数拆分所能得到的最大值,再一层for循环用来实现前面每一个数能取得到的最大值,其中dp[i]随着j一直个更新。
2.代码实现
// 常规思路:找边界值√
class Solution {
public int integerBreak(int n) {
// 拆分成数值均值的数,但拆分到什么程度呢?
if (n == 2) {
return 1;
}
if (n == 3) {
return 2;
}
if (n == 4) {
return 4;
}
int result = 1;
while (n > 4) {
result *= 3;
n -= 3;
}
result *= n;
return result;
}
}
// 动态规划
class Solution {
public int integerBreak(int n) {
// 数尽可能的均质
// 声明dp[i]数组,数值为i可拆分的最大乘积为dp[i]
int[] dp = new int[n + 1];
// 初始化dp[]数组
dp[2] = 1;
// 递推公式
for (int i = 3; i <= n; i++) {
for (int j = 1; j <= i / 2; j++) {
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
}
}
return dp[n];
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode:96. 不同的二叉搜索树 - 力扣(LeetCode)
1.思路
太深太巧妙了,根本想不出来。用构建二叉搜索树的方式并且利用其特性来做,当前根节点值确定之后其左右子树的个数就是确定的,左子树的构筑方式✖右子树的构筑个数就是以当前值为根节点的二叉树的方式,将所有值均作为根节点遍历加和一遍就是最终的结果值。第一层for循环遍历到每个节点,第二层for循环根据前面节点值推导出当前节点所能构造的最大二叉树的个数。
2.代码实现
class Solution {
public int numTrees(int n) {
// 思路:???
// 声明dp[]数组:数值为n的二叉搜索树的个数为dp[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];
}
}
3.复杂度分析
时间复杂度:O(n^2).
空间复杂度:O(n).