LintCode :不同的二叉查找树

来源:互联网 发布:如何下载photoshop软件 编辑:程序博客网 时间:2024/06/05 08:50

LintCode :不同的二叉查找树

题目

给出 n,问由 1…n 为节点组成的不同的二叉查找树有多少种?

样例

给出n = 3,有5种不同形态的二叉查找树:

1           3    3       2      1 \         /    /       / \      \  3      2     1       1   3      2 /      /       \                  \2     1          2                  3

思路

这里我们可以采用卡特兰树的方法,关于卡特兰树大家可以去维基百科卡特兰树看看。这里面刚好有提到用卡特兰树解决二叉查找树的方法,那为什么可以解决好像没说,那这里我就来简单的说一下。
卡特兰树的递推定义是这样的Cn+1=C0Cn+C1Cn1+...+Cn1C1+CnC0,这样是不是看起来很像n+1个节点的二叉树,左边有零个节点右边有n个节点的情况加上左边一个节点右边n-1各节点的情况加上。。。以此类推就可以计算出n+1个节点的二叉树有多少种情况了。然后这里给出通项公式Cn=C(2n,n)/(n+1),这里Cn就是我们要求的个数。

代码

int numTrees(int n) {        unsigned long long up = 1;        for(int i = 0; i < n; i++)            if(i % 2 == 1)                up *= 2 * n - i;            else                up *= 2;        unsigned long long down = 1;        for(int i = 0; i < n / 2; i++)            down *= n / 2 - i;        return up / down / (n + 1);    }

(哦,对了,这里为了处理阶乘溢出的问题在求阶乘的时候做了一些处理。因为分母是n!*n!分子是2n!,所以第一步约分之后分子剩下的是2n*(2n-1)*…*(n+2)*(n+1),分母则是n!,然后因为分子分母长度一样,数值上2n又是n的两倍,所以分子的偶数部分是可以跟分母消掉后只剩下2的,分子部分消掉后其实就只剩下n / 2!这一部分了,这样处理之后计算阶乘就不会溢出了。)

0 0
原创粉丝点击