原文链接:https://blog.csdn.net/u014472643/article/details/81260183
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
解题思路
使用dp[n]表示1-n可以用多少颗不同的二叉搜索树,那么
- dp[0]=1;(假设空树也是一颗树)
- dp[1]=1;
- dp[2]=2;
- dp[3]=1*2+2*1+1*1;
dp[3]为什么这么算。我们结合例子来看。
首先
1 1
\ \
3 2
/ \
2 3
这两种情况都可看成是根节点的左子树是空,右子树是2个节点的树,那么这种树就有dp[0]*dp[2]=1*2种。
3 3
/ /
2 1
/ \
1 2
而这两种情况就是左子树是2个节点的树右子树是空树。所有有dp[2]*dp[0]颗
最后一种情况就是dp[1]*dp[1]=1,把所有情况都加起来就是dp[3]的值了。
也就是说,如果根节点为k那么左子树是1至k-1共k-1个节点。右侧就是k+1至n,共n-k个节点。那么一共就用dp[k-1]*dp[n-k]棵不同的树了。
那么,求以 1 … n 为节点组成的二叉搜索树有多少种?就是1 … n为根节点的树相加了。
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 j=0;j<i;j++)
dp[i]+=dp[j]*dp[i-j-1];//状态转移方程
}
return dp[n];
}