Catalan数 卡特兰数

参考

维基百科

Catalan数——卡特兰数

引文

wiki被墙,只好土土地把内容搬运过来。。

组合数学中有非常多的组合结构可以用卡塔兰数来计数。在Richard P. Stanley的Enumerative Combinatorics: Volume 2一书的习题中包括了66个相异的可由卡塔兰数表达的组合结构。以下用n=3和n=4举若干例:

Cn表示长度2n的dyck word的个数。Dyck word是一个有n个X和n个Y组成的字串,且所有的前缀字串皆满足X的个数大于等于Y的个数。以下为长度为6的dyck words:

XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY

将上例的X换成左括号,Y换成右括号,Cn表示所有包含n组括号的合法运算式的个数:

((())) ()(()) ()()() (())() (()())

Cn表示有n个节点组成不同构二叉树的方案数。下图中,n等于3,圆形表示节点,月牙形表示什么都没有。
Catalan number binary tree example.png

Cn表示有2n+1个节点组成不同构满二叉树(full binary tree)的方案数。下图中,n等于3,圆形表示内部节点,月牙形表示外部节点。本质同上。

证明:

令1表示进栈,0表示出栈,则可转化为求一个2n位、含n个1、n个0的二进制数,满足从左往右扫描到任意一位时,经过的0数不多于1数。显然含n个1、n个0的2n位二进制数共有 {\displaystyle {2n \choose n}} {2n \choose n}个,下面考虑不满足要求的数目。

考虑一个含n个1、n个0的2n位二进制数,扫描到第2m+1位上时有m+1个0和m个1(容易证明一定存在这样的情况),则后面的0-1排列中必有n-m个1和n-m-1个0。将2m+2及其以后的部分0变成1、1变成0,则对应一个n+1个0和n-1个1的二进制数。反之亦然(相似的思路证明两者一一对应)。

从而 {\displaystyle C_{n}={2n \choose n}-{2n \choose n+1}={\frac {1}{n+1}}{2n \choose n}} C_n = {2n \choose n} - {2n \choose n + 1} = \frac{1}{n+1}{2n \choose n}。证毕。

Cn表示所有在n × n格点中不越过对角线的单调路径的个数。一个单调路径从格点左下角出发,在格点右上角结束,每一步均为向上或向右。计算这种路径的个数等价于计算Dyck word的个数:X代表“向右”,Y代表“向上”。下图为n = 4的情况:

Catalan number 4x4 grid example.svg

Cn表示通过连结顶点而将n + 2边的凸多边形分成三角形的方法个数。下图中为n = 4的情况:
Catalan-Hexagons-example.svg

Cn表示对{1, …, n}依序进出栈的置换个数。一个置换w是依序进出栈的当S(w) = (1, …, n),其中S(w)递归定义如下:令w = unv,其中n为w的最大元素,u和v为更短的数列;再令S(w) = S(u)S(v)n,其中S为所有含一个元素的数列的单位元。

Cn表示集合{1, …, n}的不交叉划分的个数.那么, Cn永远不大于第n项贝尔数. Cn也表示集合{1, …, 2n}的不交叉划分的个数,其中每个段落的长度为2。综合这两个结论,可以用数学归纳法证明:在 魏格纳半圆分布定律 中度数大于2的情形下,所有 自由的 累积量s 为零。 该定律在 自由概率论 和 随机矩阵 理论中非常重要。

Cn表示用n个长方形填充一个高度为n的阶梯状图形的方法个数。下图为n = 4的情况:
Catalan stairsteps 4.svg

Cn表示表为2×n的矩阵的标准杨氏矩阵的数量。 也就是说,它是数字 1, 2, …, 2n 被放置在一个2×n的矩形中并保证每行每列的数字升序排列的方案数。同样的,该式可由勾长公式的一个特殊情形推导得出。

Cn表示n个无标号物品的半序的个数。

小结

性质

首先,约定ca(n)为第n个Catalan数,C(2n, n)表示从2n个数字中选n个数字的组合数。

前20项,ca(0)=1, ca(1)=1…
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190

首先有ca(n)的一般通项公式为
ca(n)=C(2n, n)/(n+1)
这里写图片描述

或者
ca(n)=C(2n, n) - C(2n, n+1)
这里写图片描述

递推公式是
ca(0)=1, ca(n+1)=ca(0)*ca(n) + ca(1)*ca(n-1) + ....
这里写图片描述
或者
ca(0)=1, ca(n+1)=2*(2n+1)/(n+2)*ca(n)
这里写图片描述

常见应用

n组括号的合法表达式的个数

证明:

合法的括号表达式,应该是任意地从最左到最右扫描,左括号的数目都要大于等于右括号的数目

总的组合个数,显然是2n个括号选出n个左括号放好位置。即C(2n, n)。

那么不合法的情况是怎样呢?

考虑一个含有n个(和n个)的长度为2n的表达式,扫描到第(2m+1)位时有m+1个)和m个(
[注:这就已经不合法了]

然后,后面还有n-m-1个)和n-m个(。将这后面的n-m-1个)全部换成(,n-m个(全部换成)。那么经过这样的对换之后,后面的这串表达式中,有n-m-1个(和n-m个)

再加上原来在前面那部分的表达式,也就是说,现在整个表达式中,出现了(n-m-1)+(m)=n-1个(和(n-m)+(m+1)=n+1个)

所以说,其实这样不合法的情况,就对应了将n-1个(和n+1个)的组合。(也就是说,任意一个n-1个(和n+1个)的表达式,经过转化,都对应着一种不合法的情形)

以2组括号举例子吧,不合法的情况,按上面的例子算来是C(2n, n+1) = C(4, 3) = 4
比如说,())),是3个)和1个(,它对应着的不合法情况是())(
再比如说,)()),也是3个)和1个(,它对应着的不合法情况是))((
再比如说,))(),也是3个)和1个(,它对应着的不合法情况是)()(
再比如说,)))(,也是3个)和1个(,它对应着的不合法情况是)(()
也就是说一共有C(2n, n+1)种不合法的情形。

最后,所有的组合数-不合法的组合数
C(2n, n) - C(2n, n+1) = ca(n)

n个节点组成的不同构二叉树的方案数

这个为啥又是卡特兰数呢?

假设n个节点构造二叉树的方案数为ca(n)。

有n个节点,我先取一个作为根节点。

然后用0个节点构造左子树,n-1个节点构造右子树。

或者用1个节点构造左子树,n-2个节点构造右子树。

所以ca(n) = ca(n-1)*ca(0) + ca(n-2)*ca(1) + ….

正好符合卡特兰数的定义。

lintcode题

问题描述

http://www.lintcode.com/zh-cn/problem/unique-binary-search-trees/

不同的二叉查找树

给出 n,问由 1…n 为节点组成的不同的二叉查找树有多少种?

样例
给出n = 3,有5种不同形态的二叉查找树

笔记

用到了递推公式
ca(n) = ca(n-1)*ca(0) + ca(n-2)*ca(1) + ....

还用到了map存储中间结果,才可以通过测试。

代码

class Solution {
public:
    /**
     * @paramn n: An integer
     * @return: An integer
     */
    map<int, int> m; 

    int numTrees(int n) {
        // write your code here
        if (n == 0 || n == 1)
            return 1;
        long long res = 0;
        for (int i = 0; i < n; i++)
        {
            int num1, num2;
            if (m.find(i) != m.end())
                num1 = m[i];
            else
            {
                num1 = numTrees(i);
                m[i] = num1;
            }
            if (m.find(n-1-i) != m.end())
                num2 = m[n-1-i];
            else
            {
                num2 = numTrees(n-1-i);
                m[n-1-i] = num2;
            }

            res += num1 * num2;    
        }
        return res;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值