343.正数拆分
- dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。
- dp[i]=max(dp[i],max(j*(i-j),dp[i-j]*j)); 是d[i-j]而不是d[j]。因为d[j]已经从1到j遍历拆分了
- dp[2] = 1。0,1无法拆分
- 从前向后,且第二层循环可以优化j<i/2
-
时间复杂度:O(n^2) 空间复杂度:O(n)
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1,0);
dp[2]=1;
for(int i=3;i<=n;i++){
for(int j=1;j<i-1;j++){
dp[i]=max(dp[i],max(j*(i-j),dp[j]*(i-j)));
}
}
return dp[n];
}
};
96.不同的二叉搜索树
dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量
元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量;
元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量;
元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量;
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n+1,0);
dp[0]=1;
dp[1]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<i;j++){
dp[i]+=dp[j]*dp[i-j-1];//for(j=1;j<=n;j++)dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
};