343. 整数拆分
中等
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
但是dp[0] 和 dp[1]为什么是0值得讨论,或者说不用讨论,压根就用不着这俩数,for (int j = 1; j < i; j++)可以改成for (int j = 1; j < i - 1; j++),然后初始化dp【2】= 1。for (int i = 3; i <= n; i++) i 直接从3开始算起。
// 更新的是dp[i], 而j比i小,dp[j]都是之前存好的,j根本不需要从0遍历到i-1。
class Solution {
public int integerBreak(int n) {
int dp[] = new int[n + 1];
// 0 不是正整数,1 是最小的正整数,0 和 1 都不能拆分,因此 dp[0]=dp[1]=0
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j])); //dp[i - j]比dp[i]早几步算出,所以不必担心
// 这里为什么还要比较dp[i]呢,是因为max(j*(i-j), j*dp[i-j])
// 是相对于单独一个固定的j来说的,而j是从1到i-1的,
// 所以要比较所有的j对应的dp[i],从中取最大的
}
}
return dp[n];
}
}
96. 不同的二叉搜索树
中等
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
class Solution {
public int numTrees(int n) {
int[] dp = new int[n + 1]; // i个不同元素节点组成的二叉搜索树的个数为dp[i]
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
//对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
//一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
}