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

来源:互联网 发布:中文移动域名 编辑:程序博客网 时间:2024/05/29 00:34

题意

给定一个数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 __int128class 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 longclass 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 3const 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);    }};
0 0
原创粉丝点击