当有三个节点时,分别以1、2、3作为头节点:
元素1为头结点搜索树的数量 = 左边有0个元素的搜索树数量 * 右边有2个元素的搜索树数量
元素2为头结点搜索树的数量 = 左边有1个元素的搜索树数量 * 右边有1个元素的搜索树数量
元素3为头结点搜索树的数量 = 左边有2个元素的搜索树数量 * 右边有0个元素的搜索树数量
上述三种情况加起来,就得到有三个节点的BST树的数量
有0个元素的搜索树数量就是dp[0]
有1个元素的搜索树数量就是dp[1]
有2个元素的搜索树数量就是dp[2]
所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[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 l = 0; l < i; l++){
int r = i - l - 1;
dp[i] += dp[l] * dp[r];
}
}
return dp[n];
}
};
可以发现,后半部分计算是重复的,例如:dp[5] = dp[4]*dp[0] + dp[3]*dp[1] + dp[2]*dp[2] + dp[1]*dp[3] + dp[0]*dp[4]
,可以进行优化
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 = 0; j < i/2; j++){
dp[i] += dp[j] * dp[i-1-j] * 2;
}
if(i % 2 != 0){
// 奇数结点
dp[i] += dp[i/2] * dp[i/2];
}
}
return dp[n];
}
};