Leetcode 96 - Unique Binary Search Trees(dp or Catalan)

本文介绍了计算具有n个节点的不同二叉搜索树数量的方法,通过Catalan数的三种不同算法实现,包括直接计算、迭代更新及动态规划。

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

题意

给定一个数n,求有n个节点的BST的数目(节点的值依次是1到n)。

思路

就一Catalan数。

我们求解有3种方法:

  1. Cn=1n+1(2nn)
  2. Cn+1=2(2n+1)n+2CnC0=1
  3. dp:同Catalan数的公式

证明

首先,Catalan数的公式:Cn+1=i=0nCiCni

然后,我们来这样考虑,一个有n + 1个节点的BST,假设我们根节点的值为i + 1,那么,小于i + 1的所有值(1到i)都在左子树,大于i + 1的所有值都在右子树(n - i个),并且,每个子树都为BST。

我们设有i个节点的BST数目为pi,那么,我们假设我们以i+1作为根节点的BST数目为pipni

并且,我们可以用0到n这n + 1个数作为根节点,此时,我们有n个节点的所有BST数目为pn+1=p0pn+p1pn1+...+pnp0=i=0npipni,即Catalan数。

细节

解法1需要注意会爆long long,需要__int128
解法2会爆int需要long long

代码

//algorithm 1
#define LL __int128
class Solution {
public:
    int numTrees(int n) {
        LL res1 = 1, res2 = 1;
        for (LL i = n + 2; i <= (LL)2 * n; i++) {res1 *= i;}
        for (LL i = 1; i <= (LL)n; i++) res2 *= i;
        return res1 / res2;
    }
};


//algorithm 2
#define LL long long
class Solution {
public:
    int numTrees(int n) {
        LL x = 1; // init, x = C0
        for (int i = 1; i <= n; i++) {
            x = (LL)(2 * (2 * i - 1) * x) / (i + 1);
        }
        return x;
    }
};

//algorithm 3
const int maxn = 30;
int d[maxn];

class Solution {
public:
    int dfs(int n) {
        if (d[n] != -1) return d[n];
        d[n] = 0;
        for (int k = 0; k < n; k++) {
            d[n] += (dfs(k) * dfs(n - 1 - k));
        }
        return d[n];
    }

    int numTrees(int n) {
        memset(d, -1, sizeof(d));
        d[0] = 1;
        return dfs(n);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值