leetcode343:整数拆分
文章讲解:leetcode343
leetcode96:不同的二叉搜索树
文章讲解:leetcode96
目录
1,leetcode343 整数拆分
真是没思路。
1,确定dp数组以及下标含义:
dp[i] 拆分数字i可以得到的最大的乘积。
2,确定递推公式:
dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
(i-j)*j指的是两个数相乘,他们符合i-j+j=i,是原来的数字
dp[i-j]*j,根据数组定义,仍然可以合并成i这个数字,但是就是[i-j]拆分的结果和j相乘了
3,确定初始化
严格从dp[i]的定义来说,dp[0] dp[1] 就不应该初始化,也就是没有意义的数值。
拆分0和拆分1的最大乘积是多少?
这是无解的。
这里我只初始化dp[2] = 1,从dp[i]的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议!
4,确定遍历顺序:i是从3到n,j是从1到i-1;
5,举例子推导数组:
class Solution {
public:
int integerBreak(int n) {
int* dp = new int[n+1];
dp[2] = 1;
for (int i = 3; i <= n ; i++) {
for (int j = 1; j <= i / 2; j++) {
dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
}
}
return dp[n];
}
};
2,leetcode96 不同的二叉搜索树
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1);
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];
}
};