12个高矮不同的人,排队问题。引出卡特兰数(Catalan)

12个高矮不同的人,排队问题。引出卡特兰数(Catalan)。

      • 等价问题1
      • 等价问题2
      • 【解法】

传闻是【阿里巴巴笔试题】:12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

网上看了很多解答,但理解起来仍然费劲。索性自己动手,加强记忆。
本文用2次 “等价证明” 将答案引到卡特兰数。不正之处,欢迎指出。

等价问题1

由6个0和6个1组成一个12位的二进制数,要求从左到右扫描,任意位置,0的累计数都不小于1的累计数,求满足条件的组合有多少种。

【证明】:把12个人以A,B,C…F,L从低到高标记。将第一排位置标上0,第二排位置标上1。如下图:
12个高矮不同的人,排队问题。引出卡特兰数(Catalan)_第1张图片
然后从A-L顺序开始分配位置。根据分配顺序,得出一个由6个0和6个1组成的二进制数。又因为每次分配的都是当前最矮的人,所以分配必须遵循如下规则,才能满足题目要求。
1:无论分配0还是1,只能分配左边数过来第一个没人的位置。
2:当想分配1的时候,对应的0上必须有人。
根据以上两点,得出这个这个12位的数在任意时刻,0的累计数都不小于1的累计数。证明完毕。

等价问题2

有6个元素和一个栈,任何一个元素进栈后可选择立即出栈 or 栈里不动,比如第一个元素进栈完毕,下一个动作可以选择出栈或让后一个元素进栈,进栈次序为1、2、3、4、5、6,问不同的出栈次序有几种?

6个元素对应6个【进栈动作】和6和【出栈动作】,总计12个动作。
由【等价问题1】我们得出了一个由6个0和6个1组成的12位的二进制数,并且任意位置的0的累计数都不小于1的累计数。例如:010101010101、000111000111。
我们把0看成元素入栈,1看成元素出栈。因为栈内必须有元素才能选择【出栈动作】,所以0的累计数【入栈动作】在任意时刻都是不小于1【出栈动作】的累计数。得出等价问题1=等价问题2。证明完毕。

【解法】

基于【等价问题2】,我们假设为n个元素的进出栈操作。定义函数h(n),h(n)为n个元素进出栈次序的解。假设k为最后一个出栈的元素,比k早进栈早出栈的元素有k-1个,那么这k-1个数共有h(k-1)种出栈方式。同理,比K晚进栈早出栈的元素有h-k个,共有h(h-k)种出栈方式。求得当k最后一个出栈时,共有h(k-1)*h(h-k)种出栈方案。因为K是1-n的任意值。得出结果:h(n)=h(0)*h(n-1)+h(1)*h(n-2) + … + h(n-1)*h(0)。
当只有一个元素时,即n=1时,只有一种出栈方式,得出:h(1)=1。又根据公式h(1)=h(0)*h(0),得出h(0)=1。即h(1)=1,h(0)=1。

java代码实现h(n);将n = 6带入,计算出结果132。

    public static int h(int n){
     
        if(n == 0 || n == 1){
     
            return 1;
        }
        int r = 0;
        for (int i = 0; i < n; i++){
     
            r += h(i) * h(n - i -1);
        }
        return r;
    }

参考:
https://baike.baidu.com/item/%E5%8D%A1%E7%89%B9%E5%85%B0%E6%95%B0/6125746
https://blog.csdn.net/qq_38216239/article/details/78738785

你可能感兴趣的:(算法实战,算法,java面试题,阿里巴巴,面试,java,java)