出栈顺序(卡特兰数)

题目描述:

按照1,2,...,n-1,n的顺序入栈,问可以得到多少种出栈序列。如n=3时有1 2 3,1 3 2,2 1 3,2 3 1,3 2 1共5种出栈序列。

解题思路:

设f(n)为n个数时的方案数。

可知 f(0)=1; f(1)=1; f(2)=2;  f(3)=5;

当n=4时 :

F1    F2    F3    F4

1  2  3  4  //四种状态分别标记为F1,F2,F3,F4

若F1 位于一号位置 则之前的数字出栈顺序的情况数为F(0),在一号位置后的数字出栈顺序的情况数为f(3);

则F1 位于一号位置时方案总数为f(0)*f(3);

若F1 位于二号位置 则F1之前的位置的数字出栈顺序的情况数可知为f(1),在二号位置之后的数字的出栈顺序为f(2)。

则F1位于二号位置时方案总数为f(1)*f(2);

同理:F1位于三号位置时 方案数为 f(2)*f(1);

   F1位于四号位置时 方案数为f(3)*f(0);

由上述条件可以推出:

  f(4)=f(0)*f(3)+f(1)*f(2)+f(2)*f(1)+f(3)*f(0);

则当n未知时由以上结论可推:

  f(n)=f(0)*f(n-1)+f(1)*f(n-2)+f(2)*f(n-3)......f(n-2)*f(1)+f(n-1)*f(0);

以上就是本题的一般递推式,我们会发现 这个式子的实际时间复杂度为O(n^2);

当然不是很快,于是我们引入 卡特兰数;

所谓卡特兰数 就是 当递推式中出现 h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2) 时,

可知代数式的解为        h(n)=C(2n,n)/(n+1) (n=0,1,2,...);

它的另类递推式为          h(n)=h(n-1)*(4*n-2)/(n+1);    //本人数学弱渣 具体怎么推导请找百度君

于是乎我们的式子就化简为了 f(n)=f(n-1)*(4*n-2)/(n+1);// 优先级一定不要搞错 优先级害我找了好久bug

时间: 2024-08-06 07:56:17

出栈顺序(卡特兰数)的相关文章

出栈顺序 与 卡特兰数(Catalan)的关系

一,问题描述 给定一个以字符串形式表示的入栈序列,请求出一共有多少种可能的出栈顺序?如何输出所有可能的出栈序列? 比如入栈序列为:1 2 3  ,则出栈序列一共有五种,分别如下:1 2 3.1 3 2.2 1 3.2 3 1.3 2 1 二,问题分析 先介绍几个规律: ①对于出栈序列中的每一个数字,在它后面的.比它小的所有数字,一定是按递减顺序排列的. 比如入栈顺序为:1 2 3 4. 出栈顺序:4 3 2 1是合法的,对于数字 4 而言,比它小的后面的数字是:3 2 1,且这个顺序是递减顺序.

Catalan数与出栈顺序个数,Java编程模拟

问题描述: 队列中有从1到7(由小到大排列)的7个整数,问经过一个整数栈后,出栈的所有排列数有多少?如果整数栈的容量是4(栈最多能容纳4个整数),那么出栈的排列数又是多少? 分析:对于每一个数字i, 在它入栈之前都有 i - 1 个数字通过栈到输出队列out(不用考虑这i - 1个数字的进出栈顺序,因为可以把它们抽象成f(i - 1)), 在它之后又有 n - i个 数字入栈然后出栈(同样不需要考虑它们的进出栈顺序),这样就得到对每个最后出栈的整数i,它都有f(i - 1)*f(n - i)种出

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

原文:http://blog.csdn.net/zyearn/article/details/7758716 近日在复习数据结构,看到栈的时候,发现1个元素进栈,有1种出栈顺序:2个元素进栈,有2种出栈顺序:3个元素进栈,有5种出栈顺序,那么一个很自然地问题就是n个元素进栈,共有多少种出栈顺序? 说来惭愧,以前学数据结构的时候竟然没有考虑过这个问题.最近在看动态规划,所以“子问题”这3个字一直在我脑中徘徊,于是解决这个问题的时候我也是用类似“子问题”的方法,说白了就是递推公式. 我们把n个元素的

判断栈的出栈顺序合法性

栈的出栈顺序合法性是指给定一系列元素,如1 - N,按照从小到大的方式入栈,每个元素的出栈时机不定.题目给定一个出栈顺序,我们来判断这个出栈顺序有没有可能发生. 比如对[1,2,3,4,5,6,7,8,9]: [1,2,3,4,5,6,7,8,9]是一个合法出栈序列 [9,8,7,6,5,4,3,2,1]也是一个合法序列 [4,5,3,2,7,6,1,8,9]也是一个合法序列 [3,4,5,1,2,9,8,7,6]就是一个非法序列 判断方法有两种,一种是对每一个值,其后所有小于它的值的数是一个降

全是套路——出栈顺序

实习终于结束了,好久没有总结编程问题了,因为最近真是没怎么写程序. 今天做华为的火车进站问题,这是一道看似像全排列,其实是栈的问题. 看了一些网上的写法,掌握了一种思路,也是种投机取巧的方法: 先产生序列的全排列,然后再全排列里面去除不可能的出栈顺序. 1.全排列很好产生,用stl里面的next_permutation(begin,end) 2.判断这个排列是不是正确的出栈顺序. 就第2点: 1.给一种进栈顺序加上序号,比如4,2,8这么进栈,则4为0,2为1,8为2,以此类推.只是想表明一个顺

数据结构经典问题——出栈顺序 转载至:canlynet微博

对于数据结构的问题,如果思路稍有不对,就容易陷入逻辑混乱.我希望自己对数据结构的理解,能够给大家一点帮助.我会将所有我有过心得的问题在我的博客上写出来,欢迎大家浏览,如果有什么不对的地方,还请大家指正,有问题可以给我留言,我会尽量解决,谢谢. 声明一下我写博客的初衷:不是炫耀,而是回报.因为我在计算机方面的知识好多都从网上找到答案,因此我也 将自己搜寻整理的材料,自己写的材料,展示到网上,算是尽一份力吧. 一个经典问题如下(不愿意看思路的可以直接看红色字体部分): 一个栈的入栈序列是a,b,c,

给定入栈顺序,判断出栈顺序是否合法

题目描述:给定一个入栈序列,给定一个出栈序列,判断该出栈序列是否合法. 分析:假如入栈序列为1 2 3 4 5,判断4 5 3 2 1 是否是合法的出栈顺序. 两个序列均以数组的形式给出 从两个数组的第一个元素开始,如果栈为空,或者,栈顶元素不等于当前出栈数组当前下标对应的元素时,将当前入栈数组中下标所指向的元素进行压栈 初始状态如下: 步骤1:把 1 进行压栈,并将下标后移,如下图所示, 步骤2:依次进行判断并压栈,当4进栈后,此时栈顶元素等于出栈数组下标所指向的元素,将4出栈,如下图所示 步

写一个算法判断出栈顺序是否正确

入栈的数据:1234567 解决思路: 简单的模拟出栈入栈操作,将元素依次入栈.然后根据输入的次序依次出栈.比如给出的出栈次序是 1 4 3 7 6 2 5,首先将1入栈,发现输入数据 中的第一个正好是1.将1出栈,下面是4,由于栈是空,并且刚才只把1入栈,接下来将2 3 4依次入栈,些时栈顶元素是4,与输入数据的第二个元素相 等,将4出栈.然后3出栈,接下来处理7,由于此时栈顶元素是2,7大于2所以接下来将5 6 7依次入栈(栈中元素为7 6 5 2).然后栈顶元素与 输入数据的7比较相等,7

C++:检查出栈顺序的合法性

CheckSequence.cpp #include<iostream> #include <assert.h> using namespace std; #include <stack> bool Checksequence(int *stackIn, int *stackOut,int lenIn,int lenOut){  assert(stackIn && stackOut);  if (lenIn != lenOut)         //两个