您的位置:首页 > 产品设计 > UI/UE

LeetCode:Unique Binary Search Trees(二叉查找树)

2017-05-11 16:07 567 查看

一、BST特点

若任意节点的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;

任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

任意节点的左、右子树也分别为二叉查找树。

二、题目

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.



分析问题,可知,假设f(n)表示1~n个结点给出时,BST’s树的个数:

f(n) = f(0) * f(n-1) // 令1作为根,2~n右子树

+ f(1) * f(n-2) // 令2作为根,1作为左子树,3~n右子树

+ ……..

+ f(n-1)* f(0) //令n作根,1~n-1作为左子树。

递归形式符合卡塔兰数递归模型。



result[i]表示含有i个结点的二叉查找树的数量。然后依据上面分析的递推公式依次求出f(1), f(2),……f(n)

算法:

初始化容器前两项,后面才能开始迭代:

result.push_back(1);

result.push_back(1);

计算含i个结点时二叉查找树的种类数,j表示1~i中取任一结点作为根。所以计算方式同递归一样,左子树(j-1)*右子树(i-j).

实现递推公式

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

//直接用卡特兰数地推公式
class Solution1 {
public:
int numTrees(int n) {
long long res = 1;
if (n==0)
return 1;
for (int i=1; i<=n; ++i)
res = res*2*(2*i-1)/(i+1);
return res > INT_MAX ? 0 : res;
}
};

//利用容器的方法
class Solution2
{
public:
int numTrees(int n){
vector<int> result;
result.push_back(1);
result.push_back(1);

for(int i=2;i<=n;i++){

int sum=0;
//计算含i个结点时二叉查找树的种类数,j表示1~i中取任一结点作为根。
for(int j=1;j<=i;j++){
sum+=(result[j-1]*result[i-j]); //根J的左树个数*右树个数
}

result.push_back(sum);
}

return result.back();   //result

}

};

int main() {
Solution2 s;
cout << s.numTrees(3) << endl;
cout << s.numTrees(19) << endl;

return 0;
}


参考文献:

https://zh.wikipedia.org/wiki/%E5%8D%A1%E5%A1%94%E5%85%B0%E6%95%B0

http://blog.csdn.net/cinderella_niu/article/details/42107921#
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: