343.整数拆分
思路:动态规划五步曲
- dp[i]代表拆分数字i可以得到的最大乘积
- 递推公式:j从1开始遍历,每次取j*(i - 1)和jdp[i - j]中最大的。j(i - 1)为拆分为两个数的情况,j*dp[i - j]为拆分为两个或两个以上的情况
- 初始化:从2开始,dp[2] = 1
- 遍历顺序:i和j都是从前向后遍历
- 举例证明
class Solution {
public int integerBreak(int n) {
// dp[i]代表拆分数字i可以得到的最大乘积
int[] dp = new int[n + 1];
// 递推公式:j从1开始遍历,每次取j*(i - 1)和j*dp[i - j]中最大的
// j*(i - 1)为拆分为两个数的情况,j*dp[i - j]为拆分为两个或两个以上的情况
// 初始化:从2开始,dp[2] = 1
dp[2] = 1;
// 遍历顺序:i和j都是从前向后遍历
for (int i = 3; i < dp.length; i++) {
for (int j = 1; j < i - 1; j++) {
// 遇到大的便更新dp[i],
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
}
}
return dp[n];
}
}
96.不同的二叉搜索树
思路:动态规划五步曲 本题递推公式推导较为复杂,详情移步随想录网站
- dp[i] 表示由i个节点可以组成的二叉搜索树种类
- 递推公式:dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
- 初始化:dp[0] = 1
- 遍历顺序是i从1到n,j从1到i。
- 举例证明
class Solution {
public int numTrees(int n) {
// dp[i] 表示由i个节点可以组成的二叉搜索树种类
int[] dp = new int[n + 1];
// 递推公式:dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
// 初始化:dp[0] = 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];
}
}