已知进栈序列,求所有出栈序列||已知出栈序列求所有的入栈序列

这题写错了:

下面是错的
已知出栈序列求所有的入栈序列头条实习一面的算法题,当时没有想出来,事后想起来求出栈序列的所有入栈序列和求进栈序列的所有出栈序列其实答案是一样的,所以只要按照求进栈序列的所有出栈序列来算就行了。
why?
A序列 进栈 -> B序列
那么
B序列 进栈必然可以得到 -> A序列
然后用dfs就可以了,巧妙的很。

public class AllPopSeq {
   
   
    @Test
    public void test() {
   
   
        //已知进栈序列,求出栈序列||已知出栈序列求所有的入栈序列
        //典型的卡特兰数
        // C(n) = (2n)!/((n+1)!*n!)  n = 4 C(n) = 14
        LinkedList<LinkedList<Integer>> linkedLists = allPopSeq(new int[]{
   
   4, 3, 2, 1});
        System.out.println(linkedLists.size());
        linkedLists.forEach((l) -> {
   
   
            System.out
这是一个经典的的排列组合问题。我们可以使用卡特兰数来解。 假设有n个数字,要第k个出栈的数字,那么卡特兰数的公式为: C(n) = C(0)*C(n-1) + C(1)*C(n-2) + ... + C(n-1)*C(0) 其中C(0)=1,C(n)表示n个数字的出栈序列个数。 对于本题,n=7,根据上述公式可以计算出C(7)=429。 因此,第4个出栈的数字可能是第429/2=214个出栈序列的第4个数字。 具体方法为:先确定第一个出栈的数字,可以选择1到7中的任意一个数字,假设选择了数字i,那么剩下的数字可以分成两部分:比i小的数字和比i大的数字。因为这些数字可以不连续进栈出栈,所以比i小的数字和比i大的数字之间的顺序可以交错。比如,如果i=3,那么剩下的数字可以为2,1,4,5,6,7,也可以为2,4,1,5,7,6等等。 假设比i小的数字有x个,比i大的数字有y个,那么第一个出栈的数字是确定的,就是i。剩下的数字可以任意排列,不妨设它们的出栈序列个数为f(x,y)。 那么第k个出栈的数字必然是第214个出栈序列的第4个数字,所以我们只需要找到一个(x,y)的组合,满足f(x,y)>=4,且f(x,y)的排列组合数之和大于等于214/2=107,就可以确定第4个出栈的数字。 根据卡特兰数的公式,可以递归地计算出f(x,y)的值,具体方法为: f(x,y) = C(x+y,x) - C(x+y,x-1) 其中C(x+y,x)表示x个比i小的数字和y个比i大的数字的出栈序列个数。 因此,我们可以从小到大枚举x和y,计算f(x,y)的值,直到找到一个满足条件的组合为止。在这个过程中,需要记录已经计算出的f(x,y)的排列组合数之和,以便快速判断是否满足条件。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值