一个人的朝圣 — LeetCode打卡第 41天
知识总结
动态规划, 最重要的就是找到递推公式, 和找规律的数学题目有点像
Leetcode 96. 不同的二叉搜索树
题目说明
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
代码说明
递推公式可以理解成,
求N个节点的二叉搜索树
dp[N] = dp[0] * dp[N-1] + dp[1] * dp[N-2] +... + dp[N-1] * dp[0]
找到递推公式之后就好写了
class Solution {
public int numTrees(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
for(int i = 1; i <= n; i++){
for(int j = 0; j < i; j++){
dp[i] += dp[j] * dp[i - 1 - j];
}
}
return dp[n];
}
}
Leetcode 343. 整数拆分
题目说明
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
代码说明
自己想出来的方法, 比较好理解:
要拆分数字N,
假设N = 5,
a = 2, b = 3
dp[2] = 1, dp[3] = 2
dp[5] = max(dp[2], 2) * max(dp[3], 3)
然后再依次求dp[5] 的最大值
class Solution {
public int integerBreak(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 / 2 ; j++){
int l = Math.max(j, dp[j]);
int r = Math.max(i-j, dp[i-j]);
dp[i] = Math.max(l*r, dp[i]);
}
}
return dp[n];
}
}