LintCode :不同的二叉查找树

本文介绍了一种利用卡特兰数计算不同形态二叉查找树数量的方法,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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!这一部分了,这样处理之后计算阶乘就不会溢出了。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值