343. 整数拆分
这道题的递推公式比较难想到,将当前数 i 拆分成两部分,j 和 i-j ,那么dp[i]就的值就是j*(i-j)和 j*dp[i-j]的最大值(j从1到i-1)。
class Solution {
public int integerBreak(int n) {
//1、定义dp数组,dp[i]表示i的最大拆分乘积
int[] dp=new int[n+1];
//3、初始化方法
dp[2]=1;
//4、遍历顺序i从小到大
for(int i=3;i<=n;i++){
for(int j=1;j<=i/2;j++){//只需要遍历到 n/2 就可以,后面就没有必要遍历了,一定不是最大值。
//2、递推公式
dp[i]=Math.max(j*(i-j),Math.max(j*dp[i-j],dp[i]));//三个数取最大值的写法
}
}
return dp[n];
}
}
时间复杂度:O(n^2)
空间复杂度:O(n)
96.不同的二叉搜索树
这道题代码不多但理解起来不太容易,建议看视频理解视频教程
class Solution {
public int numTrees(int n) {
int dp[]=new int[n+1];//1、定义dp数组
dp[0]=1;//3、初始化
dp[1]=1;
for(int i=2;i<=n;i++){//4、遍历顺序
for(int j=1;j<=i;j++){
dp[i]+=dp[j-1]*dp[i-j];//2、确定递推公式
}
}
return dp[n];//模拟dp流程
}
}
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
n
)
O(n)
O(n)