https://leetcode-cn.com/problems/unique-binary-search-trees/
思路一: d p dp dp,设 d p [ i ] dp[i] dp[i]表示任意 i i i个不相等的节点所能组成的二叉搜索树的个数。因为在二叉搜索树中,我们并不关心某个节点的值,而是关心它们之间的大小关系,所以节点 1 、 2 1、2 1、2能组成的二叉搜索树的个数和节点 1 、 3 1、3 1、3能组成的二叉搜索树的个数是相等的。那么对于以 1 … n 1…n 1…n为节点的二叉搜索树,我们可以枚举根节点 i i i:当根节点为 i i i时,左子树有 i − 1 i-1 i−1个节点,右子树有 n − i n-i n−i个节点,所以有: d p [ i ] = ∑ j = 1 i d p [ j − 1 ] ∗ d p [ i − j ] dp[i]=\sum_{j=1}^{i}dp[j-1]*dp[i-j] dp[i]=j=1∑idp[j−1]∗dp[i−j]
class Solution {
public:
int numTrees(int n) {
vector<int> dp(max(n+1,3));
dp[1]=1,dp[2]=2;
if(n<=2)
return dp[n];
for(int i=3;i<=n;i++){
dp[i]=2*dp[i-1]; //以1或者n为根节点时的情况总数
for(int j=2;j<i;j++)
dp[i]+=dp[j-1]*dp[i-j]; //以j为根节点 左子树情况数*右子树情况数
}
return dp[n];
}
};
思路二:卡特兰数,证明略去。何谓卡特兰数?
f
(
0
)
=
1
f(0)=1
f(0)=1
f
(
1
)
=
1
f(1)=1
f(1)=1
f
(
n
)
=
∑
i
=
0
n
−
1
f
(
i
)
∗
f
(
n
−
i
−
1
)
,
其
中
n
>
=
2
f(n)=\sum_{i=0}^{n-1}f(i)*f(n-i-1),其中n>=2
f(n)=i=0∑n−1f(i)∗f(n−i−1),其中n>=2
满足以上条件的数就叫卡特兰数。那么它有一个更为简单的递推公式:
h
(
0
)
=
1
h(0)=1
h(0)=1
h
(
n
)
=
h
(
n
−
1
)
∗
(
4
∗
n
−
2
)
/
(
n
+
1
)
h(n)=h(n-1)*(4*n-2)/(n+1)
h(n)=h(n−1)∗(4∗n−2)/(n+1)
class Solution {
public:
int numTrees(int n) {
if(!n)
return 0;
int ans=1;
for(int i=1;i<=n;i++)
ans=ans*1ll*(4*i-2)/(i+1);
return ans;
}
};