343.整数拆分
链接:LeetCode343.整数拆分
- 确定dp数组及下标含义。dp[i]表示将整数i拆分成k(k>=2)个整数,这些整数的最大乘积为dp[i].
- 确定递推公式。根据题目中“将正整数n拆分成k个正整数(k>=2)的和”,k>=2意味着可以将正整数拆分成两个数的和,或者三个及三个以上数的和。拆分成两个数的乘积为“(i-j) * j” 拆分成三个及三个以上整数的和的乘积为(i-j)*d[j]。dp[i] = max(dp[i],max((i-j)*dp[j],(i-j) * j))0<=j<=i
- dp数组初始化。由递推公式得dp[0]=1;
- 确定遍历顺序。从前往后开始遍历
- 举例推导dp数组
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1,1);
for(int i=1;i<=n;++i){
for(int j=1;j<i;++j){
dp[i] = max(dp[i],max((i-j)*j,(i-j)*dp[j]));
}
}
return dp[n];
}
};
96.不同的二叉搜索树
链接:LeetCode96.不同的二叉搜索树
- 确定dp数组下标及含义。dp[i]表示1到i个节点组成的二叉搜索树的个数为dp[i].
- 确定递推公式。dp[i]+=dp[以j为头节点左子树节点数量]*dp[以j为头节点右子树节点数量]。j相当于是头节点的元素从1遍历到i为止。dp[i] += dp[j-1]*dp[i-j].
- 数组初始化。dp[0]=1;
- 确定遍历顺序。从头还是往后遍历。
- 举例推导dp数组
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n+1,0);dp[0]=1;
for(int i=1;i<=n;++i){
for(int j=1;j<=i;++j){
dp[i] += dp[j-1]*dp[i-j];
}
}
return dp[n];
}
};