343. 整数拆分:
题目链接
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
示例 :
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
解答:
class Solution {
public int integerBreak(int n) {
int[] dp = new int[n+1];
dp[2] = 1;
for(int i = 3; i <= n; i++) {
for(int j = 1; j <= i-j; j++) {
dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
}
}
return dp[n];
}
}
算法总结:
本题主要思路在于拆分的思路,j*(i - j) 是单纯的把整数拆分为两个数相乘,而 j×dp[i - j]是拆分成两个以及两个以上的个数相乘。所以关于dp的推导公式就是 dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));通过两个for循环可以求出最终值
96. 不同的二叉搜索树:
题目链接
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 :
输入:n = 3
输出:5
解答:
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++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
}
算法总结:
由题我们可以想到一个结点他的左右子树分布情况是一样的(如1为头结点,他的子树就是两个结点的情况),所以求n为3的情况实际上就是头结点1+头结点2+头结点3的情况,我们可以发现头结点1=左子树0结点* 右子树2结点,按照这个我们得出 dp[i] += dp[j - 1]*dp[i - j]这个推导