参考
引文
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,圆形表示节点,月牙形表示什么都没有。
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的情况:
Cn表示通过连结顶点而将n + 2边的凸多边形分成三角形的方法个数。下图中为n = 4的情况:
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的情况:
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;
}
};