96. 不同的二叉搜索树(中等)[DP][catalan数]

96. 不同的二叉搜索树

By Jalan

知识工具需求

数据结构和算法

  • DP

题解

第一次

思路

BST的中序根结点会把序列分成两个单调的段.然后每个段的根结点又会把这个段分成两个单调的段.
公式可以写作:
T ( n ) = T ( 0 ) ∗ T ( n − 1 ) + T ( 1 ) ∗ T ( n − 2 ) + T ( 3 ) ∗ T ( n − 3 ) + ⋯ + T ( n − 1 ) ∗ T ( 0 ) (1) T(n)=T(0)*T(n-1)+T(1)*T(n-2)+T(3)*T(n-3)+\cdots +T(n-1)*T(0) \tag{1} T(n)=T(0)T(n1)+T(1)T(n2)+T(3)T(n3)++T(n1)T(0)(1)

这里我们研究T在较小时的表现
分别得出
1 1 2 5 14 42等值.
这时我们有两个选择

  1. 按(1)公式从3开始推到n的值,使用一个数组保持 T 1 − T n T_1-T_n T1Tn的n个数,这个就是传统DP
  2. 非常幸运的,我们看到了一个非常熟悉的序列1 1 2 5 14 42,知道这个是catalan数我们由公式直接计算它
    C a t a l a n ( n ) = ( 2 n ) ! n ! ∗ ( n + 1 ) ! Catalan(n)=\frac{(2n)!}{n!*(n+1)!} Catalan(n)=n!(n+1)!(2n)!
    Catalan数详解
    递 归 定 义 f n = f 0 ∗ f n − 1 + f 1 ∗ f n − 2 + … + f n − 1 f 0 , 其 中 n ≥ 2 递 推 关 系 f n = 4 n − 2 n + 1 f n − 1 通 项 公 式 f n = 1 n + 1 C n 2 n 经 化 简 后 可 得 f n = C 2 n n + C 2 n n − 1 只 要 我 们 在 解 决 问 题 时 得 到 了 上 面 的 一 个 关 系 , 那 么 你 就 已 经 解 决 了 这 个 问 题 , 因 为 他 们 都 是 卡 特 兰 数 列 递归定义\\ f_n=f_0∗f_{n-1}+f_1∗f_{n−2}+…+f_{n−1}f_0,其中n≥2\\ 递推关系\\ f_n=\frac{4n−2}{n+1}f_{n−1}\\ 通项公式\\ fn=\frac{1}{n+1}C_n^{2n}\\ 经化简后可得\\ fn=C_{2n}^{n}+C_{2n}^{n-1}\\ 只要我们在解决问题时得到了上面的一个关系,那么你就已经解决了这个问题,因为他们都是卡特兰数列 fn=f0fn1+f1fn2++fn1f0n2fn=n+14n2fn1fn=n+11Cn2nfn=C2nn+C2nn1
    这里我选择的是使用通项公式计算.但是这个计算不能简单的使用int/double/long long unsigned int做统计,因为都会超范围(阶乘),double不会超,但是误差会大于1;所以这里需要做同步乘除防止超范围.

预期时间复杂度

O(1)

代码

CPP
class Solution
{
public:
    int numTrees(int n)
    {
        int i = n + 1;
        int j = 2;
        double sum = 1;
        while (i <= 2 * n && j <= n + 1)
        {
            if (i <= 2 * n)
            {
                sum *= i++;
            }
            if (j <= n + 1)
            {
                sum /= j++;
            }
        }
        return sum;
    }
};
运行用时

在这里插入图片描述

参考文献

  1. 大佬写的Catalan内容

结尾

看在我写了这么多注释的份上可以给我点个赞嘛,求求惹=]砰砰砰,给我加点写下去的油呀
@.@
也欢迎关注我的CSDN账号呀=]

                                        **开心code每一天**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值