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每一天**
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值