class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1, 0);
dp[0] = 1; // 空树
dp[1] = 1; // 1个节点
for (int i = 2; i <= n; i++) {
for (int j = 0; j < i; j++) {
dp[i] += dp[j] * dp[i - 1 - j];
}
}
return dp[n];
}
};
复杂度分析:
维度
复杂度
说明
时间复杂度
O(n²)
双重循环
空间复杂度
O(n)
dp 数组
方法二:卡特兰数
核心思路:
dp[n] 就是卡特兰数C_n:
复制代码
C_n = C(2n, n) / (n + 1)
代码实现:
cpp复制代码
class Solution {
public:
int numTrees(int n) {
long long result = 1;
for (int i = 1; i <= n; i++) {
result = result * (n + i) / i;
}
return result / (n + 1);
}
};
更安全的写法:
cpp复制代码
class Solution {
public:
int numTrees(int n) {
long long C = 1;
for (int i = 0; i < n; i++) {
C = C * 2 * (2 * i + 1) / (i + 2);
}
return (int)C;
}
};