343. 整数拆分
文档讲解 : 代码随想录 - 343. 整数拆分
状态:再次回顾。
动态规划五部曲:
-
确定dp数组(dp table)以及下标的含义
dp[i]的定义为:分拆数字i,可以得到的最大乘积为dp[i]
。 -
确定递推公式
dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});
-
dp数组如何初始化
dp[2] = 1
-
确定遍历顺序
从前向后遍历,先有dp[i - j]再有dp[i]。 -
举例推导dp数组:
举例当n为10 的时候,dp数组里的数值,如下:
本题代码:
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(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];
}
};
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( n ) O(n) O(n)
96.不同的二叉搜索树
文档讲解 : 代码随想录 - 96.不同的二叉搜索树
状态:再次回顾。
动态规划五部曲:
-
确定dp数组(dp table)以及下标的含义
dp[i]的定义为:1
到i
为节点组成的二叉搜索树的个数为dp[i]
。 -
确定递推公式
dp[i] += dp[j - 1] * dp[i - j];
其中j-1
为j为头结点左子树节点数量,i-j
为以j
为头结点右子树节点数量 -
dp数组如何初始化
dp[0] = 1
-
确定遍历顺序
节点数为i的状态是依靠i
之前节点数的状态。那么遍历i
里面每一个数作为头结点的状态,用j来遍历。 -
举例推导dp数组:
n为5时候的dp数组状态如图:
本题代码:
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];
}
};
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( n ) O(n) O(n)