持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
做动态规划的第三天,明显难度上升
343 整数拆分
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积
题目给的例子:
示例 1:
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
1.新建一个dp二维数组
因为正整数n,所以取n+1,要不然根据下标会少一个数
2.分析公式:
由例子得,比如10,可以拆分成
10=1+9,2+8,3+7,4+6,5+5 后面就是两个数字相反,乘积还是相同
还可以再拆,10=3+7,7=1+6,2+5,3+4,推出 10=3+(3+4)
由此可得分为两种
a.一种是直接拆开,不拆第二次
b.已经拆开,继续拆
所以dp[i],需要从1开始遍历j,有上述两种方式得到dp[i]
dp[i] = Math.max(j*(i-j),j*dp[i-j]);
有一种特殊情况,就是要比原有得数字大,才满足题意,所以修改如下
dp[i] = Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));
3.初始化
dp[1] = 1;
dp[2] = 1;
所以循环i可以从3开始
4.完整代码
public int integerBreak(int n) {
int[] dp = new int[n+1];
dp[2] = 1;
dp[1] = 1;
for(int i=3;i<=n;i++){
for(int j=1;j<i-1;j++){
dp[i] = Math.max(dp[i],Math.max(j*dp[i-j],j*(i-j)));
}
}
return dp[n];
}
96 不同的二叉搜索树
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
输入:n = 3
输出:5
示例 2:
输入:n = 1
输出:1
思路:
1.新建一个dp二维数组
n个节点,且n=0的时候,虽然是一个二叉树,但是没有意义
2.分析公式:
以n=3为例,root节点为1时,总数= 右子树有2个元素的搜索树的数量*左子树有0个元素的搜索树数量
root节点为2时,总数=右子树有1个元素的搜索树的数量*左子树有1个元素的搜索树数量
root节点为3时,总数=右子树有0个元素的搜索树的数量*左子树有3个元素的搜索树数量
换成公式为: dp[1] =dp[2]*dp[0]
dp[2] =dp[1]*dp[1]
dp[3] =dp[0]*dp[2]
可以看出规律,假设root节点为i,那么左子树的范围一定是(1,i-1),因为是二叉搜索树
所以右子树范围一定是(i+1,n),所以,左子树的个数为i-1,右子树的个数为n-i
那么就转化求:dp[i-1]*dp[n-i]
dp[i] += dp[j-1]*dp[i-j]
3.初始化
dp[0] = 1; 虽然是一个二叉树,但是没有意义
dp[1] = 1;
4.完整代码
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];
}