题目链接:Unique Binary Search Trees
Given n, how many structurally unique BST’s (binary search trees) that store values 1…n?
For example,
Given n = 3, there are a total of 5 unique BST’s.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
这道题的要求是求用1…n生成结构不同的二叉搜索树(BST)的数量。
二叉搜索树,顾名思义,它是一个二叉树,即每个节点下面最多有2个子节点。同时为了便于搜索的特性,二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:
- 若其左子树不空,则左子树上所有结点的值均小于根结点的值;
- 若其右子树不空,则右子树上所有结点的值均大于根结点的值;
- 其左、右子树也分别为二叉搜索树。
1…n的所有结构不同的二叉搜索树的数量,可以注意到这是一个卡特兰数。
-
递归分治
生成二叉搜索树,可以选取1…n中的任意节点i当根节点,然后比i小的放到左子树,比i大的放到右子树即可。因此i需要遍历1…n,然后累加每次情况。其中每次左子树有i-1个点,右子树有n-i个点,左右子树的数量需要递归处理,再相乘即为根节点是i情况下不同二叉搜索树的数量。
时间复杂度:O(???)
空间复杂度:O(???)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution
{
public:
int numTrees(int n)
{
if(n == 0 || n == 1)
return 1;
int sum = 0;
for(int i = 1; i <= n; ++ i)
sum += numTrees(i - 1) * numTrees(n - i);
return sum;
}
};
-
动态规划
动态规划的思路就是记录上面递归处理子问题的解即可。
时间复杂度:O(n^2)
空间复杂度:O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution
{
public:
int numTrees(int n)
{
vector<int> dp(n + 1, 0);
dp[0] = 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];
}
};
-
卡特兰数
由于该问题是卡特兰数,因此可以选择计算卡特兰数的方案处理该问题。
- h(n)= h(0)h(n-1)+h(1)h(n-2) + … + h(n-1)h(0) (n>=2)
- h(n)=h(n-1)(4n-2)/(n+1) (n>=1)
- h(n)=C(2n,n)/(n+1) (n=0,1,2,…)
- h(n)=c(2n,n)-c(2n,n+1)(n=0,1,2,…)
利用第3个公式即可。
时间复杂度:O(n)
空间复杂度:O(1)
1
2
3
4
5
6
7
8
9
10
11
class Solution
{
public:
int numTrees(int n)
{
int h = 1;
for(int i = 2; i <= n; ++ i)
h = h * (4 * i - 2) / (i + 1);
return h;
}
};