引
Catalan数,中文卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中的数列。一旦入坑,你会发现这个数列相当有意思,能够应用于很多看起来特别复杂的计算场景,当然,并能将之迎刃而解。
wikipedia定义:卡塔兰数是组合数学中一个常在各种计数问题中出现的数列。以比利时的数学家欧仁·查理·卡特兰(1814–1894)命名。历史上,清代数学家明安图(1692年-1763年)在其《割圜密率捷法》最早用到“卡塔兰数”,远远早于卡塔兰。有中国学者建议将此数命名为“明安图数”或“明安图-卡塔兰数”。
一般通项: An=1n+1Cn2n=Cn2n−Cn−12n
我的“入坑”则归功于几天前在搜狐的实习生线上笔试上做到的一道题:key值分别为1,2,3,4,5,6的6个节点能够组成多少中不同的二叉搜索树(BST)。试后,我在网上查到了很多对catalan数的讨论,发现套用它的公式可以解决好多问题,甚至有不少问题都是互联网笔试中老生常谈的:
- n对括号 有多少种组合
- 矩阵链乘,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,有几种括号化的方案
- n个元素入栈 有多少种出栈顺序
- 凸多边形通过互不相交的对角线划分,求划分方案数
- 在圆上选择2n个点,将这些点连接起来,使得所得到的n条线段不相交的方法数
- 2n边的凸多边形,连接对角线 可以分出三角形的个数
- n × n格点中不越过对角线的单调路径的个数(上班路线选择问题)
- 给定n个节点组成二叉搜索树个数(或组成的二叉树形态数)
- 2n个高矮不同的人 站成两排 保证后排对应的人比前排高 每排从左到 右越来越高 有多少种排列方式
- 《编程之美》4.3中的买票找零问题:2n个人排队买票,其中n个人持50元,n个人持100元。每张票50元,且一人只买一张票。初始时售票处没有零钱找零。请问这2n个人一共有多少种排队顺序,不至于使售票处找不开钱
- (腾讯笔试)在图书馆一共6个人在排队,3个还《面试宝典》一书,3个在借《面试宝典》一书,图书馆此时没有了面试宝典了,求他们排队的总数?
- (阿里笔试)说16个人按顺序去买烧饼,其中8个人每人身上只有一张5块钱,另外8个人每人身上只有一张10块钱。 烧饼5块一个,开始时烧饼店老板身上没有钱。 16个顾客互相不通气,每人只买一个。 问这16个人共有多少种排列方法能避免找不开钱的情况出现。
这类问题恐怕每道题单拿出来都是一道令人头疼的算法编程题,仔细观察不难发现这些问题都是有一些共性的,比如都是求方案的个数,而且很多问题的应用场景都是一样的,只不过在形式在做了变形,如:(1)和(2)是一类,(4)和(5)是一类,(9)(10)(11)(12)是一类。当然,在本质上,以上所有问题均能抽象为一种问题:一种通解符合卡特兰数列的问题。(实际上,根据求解思路,我把它归纳为两类同构问题,这两种思路都能推出卡特兰数列,后面会讨论到)
内容提要
本文将首先讨论序列类场景的经典例题单调路径问题及解法,并给出几种常见的同构问题,然后以N节点二叉树问题为切入点,介绍该类问题的一般解法及思考方式,最后给出卡特兰数的一般性定义,总结卡特兰数的数学思想。文末将附上相关参考文献的链接