美文网首页
卡特兰数

卡特兰数

作者: yuansip | 来源:发表于2016-12-01 18:02 被阅读0次

C(n) = C(0)C(n-1) + C(1)C(n-2) + ... + C(n-1)C(0)
或者C(n) = (2n)! / (n!
(n+1)!)
C(0) = C(1) = 1
满足这样条件的序列就是卡特兰数。

  1. 1到n的整数能构建多少不同的BST(binary search tree)?
    任一个整数做根节点时,其左右BST子树的个数乘积就是这个整数做根节点的BST的个数,而1到n任一个整数做根节点的子树的个数相加,就是该问题的答案。例如:设该问题的解为h(n), 1做根节点,则左子树不可能有节点,而2~n共n-1个节点构成了右子树,所以BST个数是h(0)h(n-1), k做根节点,则左子树只能有k-1个节点,而右子树只能有n-k个节点,此时BST个数是h(k-1)h(n-k), 综上, h(n) = h(0)h(n-1) + h(1)h(n-2) + ... + h(k-1)h(n-k) + ... + h(n-1)h(0)。可以看出该问题的答案实际上就是求解卡特兰数
  2. 设有无穷大的栈,已知入栈序列为1,2,...,n,求所有可能的出栈序列的个数
    假设最后一个出栈的元素是k, 1 <= k <= n, 则显然在k入栈之前,1到k-1已经全部出栈了;而在k入栈后,k+1到n开始入栈,并在k出栈前全部出栈完毕。设该问题的解是h(n), 则显然当最后一个出栈的元素是k时,左右可能的出栈序列是h(k-1)h(n-k),
    而h(n) = h(0)
    h(n-1) + h(1)h(n-2) + ... + h(k-1)h(n-k) + ... + h(n-1)*h(0)。可以看出该问题的答案实际上也是求解卡特兰数。
  3. 有n对(),求所有可能的括号序列个数,比如n = 2时(()), ()()
    我们可以把'('看成入栈,')'看成出栈,所以问题3实际上就等同于问题2
  4. 有2n个人买票,票价是5元,n个人有5元,n个人有10元,剧场没有零钱,有多少种可能排队,可以让所有人都买到票。
    我们可以吧5元看成入栈,10元看成出栈,所以问题4实际上就等同于问题2

问题2还可以用另一种角度来看,假设1代表入栈,0代表出栈,在2n位二进制数中填入n个1的方案数为c(2n,n),不填1的其余n位自动填0。从中减去不符合要求(由左而右扫描,0的累计数大于1的累计数)的方案数即为所求。
不符合要求的数的特征是由左而右扫描时,必然在某一奇数位2m+1位上首先出现m+1个0的累计数和m个1的累计数,此后的2(n-m)-1位上有n-m个 1和n-m-1个0。如若把后面这2(n-m)-1位上的0和1互换,使之成为n-m个0和n-m-1个1,结果得1个由n+1个0和n-1个1组成的2n位数,即一个不合要求的数对应于一个由n+1个0和n-1个1组成的排列。
反过来,任何一个由n+1个0和n-1个1组成的2n位二进制数,由于0的个数多2个,2n为偶数,故必在某一个奇数位上出现0的累计数超过1的累计数。同样在后面部分0和1互换,使之成为由n个0和n个1组成的2n位数,即n+1个0和n-1个1组成的2n位数必对应一个不符合要求的数。
因而不合要求的2n位数与n+1个0,n-1个1组成的排列一一对应。
显然,不符合要求的方案数为c(2n,n+1)。由此得出输出序列的总数目=c(2n,n)-c(2n,n+1)=c(2n,n)/(n+1)=h(n)。

public class Solution {
    static void parenthese(String currentSeq, int leftLNum, int leftRNum) {
        if (leftRNum == 0) {
            System.out.println(currentSeq);
            return;
        }
        if (leftLNum == 0) {
            for (int i = 0; i < leftRNum; i++) {
                currentSeq += ")";
            }
            System.out.println(currentSeq);
            return;
        }
        if (leftLNum == leftRNum) {
            parenthese(currentSeq + "(", leftLNum - 1, leftRNum);
        } else {
            parenthese(currentSeq + "(", leftLNum - 1, leftRNum);
            parenthese(currentSeq + ")", leftLNum, leftRNum - 1);
        }
    }
    public static void parenthese(int n) {
        parenthese("", n, n);
    }
    static void printStack(final String seq) {
        int oneCount = 0;
        int zeroCount = 0;
        for (int i = 0; i < seq.length(); i++) {
            if (seq.charAt(i) == '1') {
                oneCount++;
            } else {
                if (seq.charAt(i - 1) == '1') {
                    System.out.print(oneCount);
                    zeroCount = 0;
                } else {
                    System.out.print(oneCount - zeroCount);
                }
                zeroCount++;
            }
        }
        System.out.print("\n");
    }
    static void stack(String currentSeq, int leftPushNum, int leftPopNum) {
        if (leftPopNum == 0) {
            printStack(currentSeq);
            return;
        }
        if (leftPushNum == 0) {
            for (int i = 0; i < leftPopNum; i++) {
                currentSeq += "0";
            }
            printStack(currentSeq);
            return;
        }
        if (leftPushNum == leftPopNum) {
            stack(currentSeq + "1", leftPushNum - 1, leftPopNum);
        } else {
            stack(currentSeq + "1", leftPushNum - 1, leftPopNum);
            stack(currentSeq + "0", leftPushNum, leftPopNum - 1);
        }
    }
    public static void stack(int n) {
        stack("", n, n);
    }
    public static void main(String[] argc) {
        parenthese(4);
        stack(4);
    }
}

参考阅读

求所有可能出栈序列
判断出栈序列是否合法
卡特兰数_百度百科
从《编程之美》买票找零问题说起
Unique Binary Search Trees

相关文章

  • Golang 实现卡特兰数

    Golang 实现卡特兰数 卡特兰数又称卡塔兰数,卡特兰数是组合数学中一个常出现在各种计数问题中的数列。前20项为...

  • 卡特兰数:hdu-2067 小兔的棋盘&&火车出栈问题

    卡特兰数,一串神奇的数字,1,2,5,14...... 首先了解一下卡特兰数. 卡特兰数(好像很有用的说) - C...

  • AVL

    LOG(n) 卡特兰数 叉姐

  • 数学 | 卡特兰数

    卡特兰数 定义 卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出...

  • 卡特兰数

  • 卡特兰数

    之前看算法导论时,讲了给定几个数字,能构造出几种二叉树,当时只想到排列组合的解决方法,极其复杂又不好记,过段时间还...

  • 卡特兰数

    https://zhuanlan.zhihu.com/p/31317307 火车进出栈问题和腾讯那道猜拳游戏是一样...

  • 卡特兰数

    卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 :1, 2, 5, 14, 42,132, 429,...

  • 卡特兰数

    名字来源比利时数学家卡塔兰。卡塔兰:Catalan 数列满足 通项: 给定n个节点,能构成的二叉搜索树个数为Cn。...

  • 卡特兰数

    题:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?解:...

网友评论

      本文标题:卡特兰数

      本文链接:https://www.haomeiwen.com/subject/xzoxmttx.html