题解 | 有多少个不同的二叉搜索树
有多少个不同的二叉搜索树
https://www.nowcoder.com/practice/16d23f940a084023b3be6019262589dc
解题思路
- 定义
表示
个节点能构成的不同二叉搜索树的数量
- 对于每个节点数
:
- 可以选择
到
中的任何一个数作为根节点
- 左子树由小于根节点的数构成
- 右子树由大于根节点的数构成
- 可以选择
- 状态转移方程:
,
从
到
- 其中
是左子树节点数,
是右子树节点数
- 边界条件:
代码
#include <iostream>
#include <vector>
using namespace std;
int numTrees(int n) {
vector<long long> dp(n + 1, 0);
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= i; j++) {
dp[i] += dp[j-1] * dp[i-j];
}
}
return dp[n];
}
int main() {
int n;
cin >> n;
cout << numTrees(n) << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static int numTrees(int n) {
long[] dp = new long[n + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= i; j++) {
dp[i] += dp[j-1] * dp[i-j];
}
}
return (int)dp[n];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(numTrees(n));
sc.close();
}
}
def num_trees(n):
dp = [0] * (n + 1)
dp[0] = dp[1] = 1
for i in range(2, n + 1):
for j in range(1, i + 1):
dp[i] += dp[j-1] * dp[i-j]
return dp[n]
n = int(input())
print(num_trees(n))
算法及复杂度
- 算法:动态规划(卡特兰数)
- 时间复杂度:
,需要两层循环
- 空间复杂度:
,需要一个
数组