已知\(n\)个数的入栈序列,求一共有多少种出栈序列

这个经典问题有两种解法。

解法一:

设\(f(x)\)为\(x\)个数入栈后,再全部出栈的序列数量

假设我们有\(4\)个数\(a,b,c,d\), 我们来看\(a\)的出栈顺序.

假如\(a\)第一个出栈,那么后面还有\(3\)个数没有出栈,因此方法数是\(f(3)\).

假设\(a\)第二个出栈,那么\(a\)的前面有\(1\)个数已经出栈,后面还有\(2\)个数没有出栈,因此方法数为\(f(1) * f(2)\).

假设\(a\)第三个出栈,那么\(a\)的前面有\(2\)个数已经出栈,后面还有\(1\)个数没有出栈,因此方法数为\(f(2) * f(1)\).

同理,\(a\)第四个出栈的方法数为\(f(3)\).

那么我们就可以得到\(f(4) = f(3) + f(1) *f(2) + f(2)*f(1) +f(3)\).

对于\(n\)来推广一下,可以得到:\(f(n)=\sum_{i=1}^{n}f(i - 1)*f(n-i)\).

不难发现这就是卡特兰数,这里就不在赘述了。

解法二:

我们假设\(-1\)表示出栈,\(1\)表示入栈,这样我们就可以用\(-1\)和\(1\)组成的序列来表示出入栈操作。

首先来限定一些条件,一个合法的序列\(0\)和\(1\)的数量一定是相等的。并且序列的前缀和一定是不小于\(0\)的。

了解了上面两个条件后,我们知道所有的序列数为\(C^{\ n}_{2n}\),因为\(-1\)和\(1\)的数量相同。在这\(C^{\ n}_{2n}\)个序列中,存在不合法的序列,即前缀和小于\(0\)的序列,我们想要知道这些不合法的序列有多少。

假设我们有一个序列\(1,-1,-1,1,-1,1\),这里在第三个下标,我们发现了它的前缀和小于\(0\),因此它不合法。再来推广一下,在这所有\(C^{\ n}_{2n}\)个序列中,不合法的序列它的前缀和一定在某一处小于\(0\).

接下来,我们将序列开头到不合法下标的这一段进行取反。首先拿上面的例子来进行说明,取反后得到:\(-1,1,1,1,-1,1\),不难发现,现在得到的序列\(+1\)比\(-1\)多出一个.

现在再来进行推广,我们截取的不合法序列段(从开头到不合法前缀和下标),这一段中的\(-1\)一定比\(+1\)多一个,那么将这一段取反后所得到的总序列中的\(+1\)一定比\(-1\)多一个。

不难发现,不合法的序列一定对应唯一一个取反后的序列,并且取反后的序列中\(+1\)有\(n+1\)个,\(-1\)有\(n-1\)个,那么根据这个条件,我们就可以得到所有不合法的序列数量为\(C_{2n}^{n+1}\)或者\(C^{n-1}_{2n}\)(因为他两相等)。

最后,合法的序列数为:\(C^{\ n}_{2n}-C_{2n}^{n+1\ or\ n-1}\).

这个解法的关键在于,不合法的序列一定唯一对应一个取反后的序列,那么我们可以算出所有取反后的数列有多少种(根据\(+1\)有\(n+1\)个,\(-1\)有\(n-1\)个的性质),来对应出不合法的序列数,从而得到答案.

因为感觉这种解法非常的巧妙,因此想写篇博客来总结一下.

已知n个数的入栈序列,求一共有多少种出栈序列 (卡特兰数)的更多相关文章

  1. n个元素的入栈顺序有多少种出栈顺序?

    问题:w1.w2.w3.w4.w5,5个元素将会按顺序入栈,求出栈顺序有多少种情况. 先写一下结论方便记忆: 1个元素:1种 2个元素:2种 3个元素:5种 4个元素:14种 5个元素:42种 简单的 ...

  2. 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数

    找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数 #include<iostream>using namespace s ...

  3. 求入栈顺序为1234……N的序列的所有可能的出栈序列

    class Program { private static void Fun(int x, int n, Stack<int> stack, List<int> outLis ...

  4. 已知ip地址和其子网掩码如何求网络号子网号主机号

    已知ip地址为10.130.89.95,其子网掩码为255.255.255.224,求其网络号.子网号和主机号. 要看子网掩码变长在第几节,255.255.255.224是在第四节借了位 把224转换 ...

  5. 已知空间三点组成的面求该面上某点的Z值

    已知空间三点,那么可以就可以确定空间三点组成的平面.此时可以根据某一点的X值和Y值,来求取该点在平面上的Z值.这个过程对于求三角面片上某点的高程或者权值特别有用,其本身也可以看作一种线性插值. 其算法 ...

  6. DS Tree 已知先序、中序 => 建树 => 求后序

    参考:二叉树--前序和中序得到后序 思路历程: 在最初敲的时候,经常会弄混preorder和midorder的元素位置.大体的思路就是在preorder中找到根节点(根节点在序列的左边),然后在mid ...

  7. poj 1363 Rails in PopPush City &&【求堆栈中合法出栈顺序次数】

    问题如下: 问题 B: Rails 时间限制: Sec 内存限制: MB 提交: 解决: [提交][状态][讨论版] 题目描述 There is a famous railway station in ...

  8. n个元素进栈,共有多少种出栈顺序?

    1.基于栈的问题分析 我们把n个元素的出栈个数的记为f(n), 那么对于1,2,3, 我们很容易得出:                                   f(1) = 1     / ...

  9. c语言将2进制数转化为10进制数(栈的初始化,进栈,出栈)

    //c语言描述 将2进制转化为10进制 #include <stdio.h> #include <stdlib.h> #include <math.h> #defi ...

  10. 已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数

    #include<iostream> using namespace std; //#define maxn 2000010 #include<stdio.h> //int a ...

随机推荐

  1. C# 定时任务模拟,请求二十万数据

    定时器请求二十万数据 最近遇到一个问题,api接口,因为数据内容转换处理.一页1万条数据处理速度3秒以上.假设二十万条数据,分页请求二十次,总共花费时间1分钟以上. 解决这个问题,我第一时间想到并发, ...

  2. Linux应用开发之【多线程开发-回调函数】

    原来我一直都不懂回调函数是什么 ... Callback Function 定义:通过函数指针调用的函数 在理解这个回调函数之前我们需要先了解回调机制 回调机制在编程中体现在:特定的情况发生后,返回并 ...

  3. 2020/03/25 CSS相关知识点

    2020-03-25 16:35:03 又是一个风和日丽的下午!今天的内容比较多 真是令人头大 ,手速又慢所以缺的可能比较多,而且这东西还是多靠实践为好. 文件下载地址: https://share. ...

  4. GFF2GTF.py2

    import sys inFile = open(sys.argv[1],'r') for line in inFile: #skip comment lines that start with th ...

  5. PCB封装设计建议:

    1,通孔型元器件建议孔直径比元器件管脚直径大0.2-0.3mm左右,焊盘铜皮外沿一般是0.3-1mm(相当于直径应该加0.6-2mm)宽大元件可再大一点,对于设计单面板的,则最小铜皮外沿应大于1mm以 ...

  6. Java基础学习——Arrays类

    1.数组复制 Arrays.copyOfRange(original, from, to) 此方法与System.arraycopy类似. 不同的是System.arraycopy需要提前声明目标数组 ...

  7. 第一章 excel与数据格式

    part1 数据缘何而来 excel中常见的文件格式有xls与xlsx,推荐后者(空间小.容量大.速度快等特点) 单个excel文件为工作簿,其下包含工作表sheet(最多255),sheet中的每个 ...

  8. 全新TI AM62xx系列核心板上市,小小身板蕴藏巨大势能!

    2011年TI推出AM335x,成为了此后市场上最受欢迎的通用工业级ARM处理器,并广泛应用于工业HMI, 医疗电子,机器人,能源,汽车等领域.随着工业4.0的发展,HMI人机交互.工业工控.医疗等领 ...

  9. git操作回顾,从零入手

    1.可在极狐或者git上直接通过http克隆项目,或者通过ssh密钥,这样就不用每次上传代码需要输入密码和验证 ssh密钥参考如下 (80条消息) git如何生成ssh密钥 git生成配置ssh密钥k ...

  10. CSS clip-path 属性

    属性定义及使用说明 clip-path 属性使用裁剪方式创建元素的可显示区域.区域内的部分显示,区域外的隐藏.可以指定一些特定形状. 注意: clip-path 属性将替换已弃用的 clip 属性. ...