一,问题描述

给定一个以字符串形式表示的入栈序列,请求出一共有多少种可能的出栈顺序?如何输出所有可能的出栈序列?

比如入栈序列为: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,且这个顺序是递减顺序。同样地,对于数字 3 而言,比它小的后面的数字是: 2 1,且这个顺序是递减的。....

出栈顺序:1 2 3 4 也是合法的,对于数字 1 而言,它后面没有比它更小的数字。同样地,对于数字 2 而言,它后面也没有比它更小的数字。

出栈顺序:3 2 4 1 也是合法的,对于数字 3 而言,它后面比 3 小的数字有: 2 1,这个顺序是递减的;对于数字 2 而言,它后面的比它 小的数字只有 1,也算符合递减顺序;对于数字 4 而言,它后面的比它小的数字也只有1,因此也符合递减顺序。

出栈顺序:3 1 4 2 是不合法的,因为对于数字 3 而言,在3后面的比3小的数字有:1 2,这个顺序是一个递增的顺序(1-->2)。

因此,当给定一个序列时,通过这个规律 可以轻松地判断 哪些序列是合法的,哪些序列是非法的。

②给定一个入栈顺序:1  2  3 .... n,一共有多少种合法的出栈顺序?参考:百度百科卡特兰数

答案是 卡特兰数。即一共有:h(n)=c(2n,n)/(n+1) 种合法的出栈顺序。

如果仅仅只需要求出一共有多少种合法的出栈顺序,其实就是求出组合 C(2n,n)就可以了。而求解C(2n,n),则可以用动态规划来求解,具体可参考: 排列与组合的一些定理

三,代码实现

给定一个入栈顺序,比如 1 2 3 ,如何输出所有可能的出栈顺序?

思路①:先求出入栈顺序的所有排列(即全排列),并将排列保存到一个LinkedList<String>中,然后依次遍历每一个序列,判断该序列是否是合法的序列。

所谓合法的序列,就是满足上面的规律1:对于出栈序列中的每一个数字,在它后面的、比它小的所有数字,一定是按递减顺序排列的。 关于如何求解一个序列的全排列,可参考:JAVA求解全排列

完整代码实现如下:(实现得不好,感觉比较复杂)

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;public class AllStackPopOrder {public static LinkedList<String> allPermutation(String str){if(str == null || str.length() == 0)return null;//保存所有的全排列LinkedList<String> listStr = new LinkedList<String>();allPermutation(str.toCharArray(), listStr, 0);//print(listStr);//打印全排列return listStr;}private static void allPermutation(char[] c, LinkedList<String> listStr, int start){if(start == c.length-1)listStr.add(String.valueOf(c));else{for(int i = start; i <= c.length-1; i++){//只有当没有重叠的字符 才交换if(!isSwap(c, start, i)){swap(c, i, start);//相当于: 固定第 i 个字符allPermutation(c, listStr, start+1);//求出这种情形下的所有排列swap(c, start, i);//复位
                }}}}private static void swap(char[] c, int i, int j){char tmp;tmp = c[i];c[i] = c[j];c[j] = tmp;}private static void print(LinkedList<String> listStr){Collections.sort(listStr);//使字符串按照'字典顺序'输出for (String str : listStr) {System.out.println(str);}System.out.println("size:" + listStr.size());}//[start,end) 中是否有与 c[end] 相同的字符private static boolean isSwap(char[] c, int start, int end){for(int i = start; i < end; i++){if(c[i] == c[end])return true;}return false;}public static LinkedList<String> legalSequence(LinkedList<String> listStr){Iterator<String> it = listStr.iterator();String currentStr;while(it.hasNext())//检查全排列中的每个序列
        {currentStr = it.next();if(!check(currentStr))it.remove();//删除不符合的出栈规律的序列
        }return listStr;}//检查出栈序列 str 是否 是合法的出栈 序列private static boolean check(String str){boolean result = true;char[] c = str.toCharArray();char first;//当前数字.int k = 0;//记录 compare 数组中的元素个数char[] compare = new char[str.length()];for(int i = 0; i < c.length; i++){first = c[i];//找出在 first 之后的,并且比 first 小的数字for(int j = i+1; j < c.length; j++){if(c[j] > first)continue;else{compare[k++] = c[j];//将比当前数字小的 所有数字 放在compare数组中
                }}if(k == 0)continue;else{for(int m = 0; m < k-1; m++)//判断 compare 数组是否是 递减的顺序
                {if(compare[m] < compare[m+1]){result = false;//不符合递减顺序return result;}}}k=0;}return result;}//hapjin testpublic static void main(String[] args) {String str = "1234";LinkedList<String> listStr = legalSequence(allPermutation(str));print(listStr);}
}

View Code

思路②:直接求出合法的出栈序列。【而不是像思路①那样:先求出所有可能的出栈序列(求全排列),然后再找出合法的出栈序列。】

待完成。

四,参考资料

JAVA求解全排列

出栈顺序(卡特兰数)

可能的出栈顺序

转载于:https://www.cnblogs.com/hapjin/p/5758083.html

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

  1. 堆栈出栈顺序个数详解——卡兰特数

      参考了多篇博客之后,终于弄懂了,写下了方便以后复习!首先简单介绍一下堆栈的运行方式,先入后出,First In Last Out(FILO),即若我们将1-4顺序放入堆栈中,则出栈顺序为4 3 2 ...

  2. 卡特兰数 Catalan number

    卡特兰数 Catalan number 卡特兰数前几项为 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 74290 ...

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

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

  4. 算法基础 - 数论 | 组合数学 卡特兰数(Catalan number)定义、证明及例题

    写在前面:卡特兰数这东西感觉挺常用的,并且公式很简单,那就花一下午总结一下,学点皮毛吧(反正遇到我还是不会 ) [PDF] 大三上组合数学课堂讲义 文章目录 卡特兰数定义 卡特兰数的性质 卡特兰数证明 ...

  5. 元素入栈顺序确定,共有多少种出栈顺序?----Python

    文章目录 问题描述 对栈的理解 题目的思考 python代码 卡特兰数 扩展思路 问题描述 前几天看到一个题目,假设五个元素的入栈顺序为e1.e2.e3.e4.e5,那么共有多少种出栈顺序?一时之间思 ...

  6. 卡特兰数[catalan数]`

    定义: 卡特兰数又叫卡塔兰数,是组合数学中一类常用的数列.前几项为:1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 74290 ...

  7. 出栈顺序问题讲解 蓝桥杯

    引言:最近刷数据结构的题,刷到一组元素入栈,他的出栈顺序有可能是哪些时卡住,之前没有关注此类问题,便写下总结 先通过几个例题讲解下出栈顺序问题 1. 一个栈的入栈序列是a,b,c,d,e则栈的不可能的 ...

  8. 卡特兰数Catalan Number

    Catalan Number满足下列递推公式: N个元素元素进栈,多少种出栈方式 考虑A.B.C.D依次进栈,那么所有的出栈顺序是下列4种情况的并集: 1)A第一个出栈.肯定是A进栈后马上出栈,剩下B ...

  9. 数据结构----出栈顺序有效性的判断

    1 问题描述 问题1:若元素 a,b,c,d,e,f 顺序进栈, 则不准许的出栈顺序是 A. d,c,e,b,f,a    B. c,b,d,a,e,f    C. b,c,a,e,f,d    D. ...

最新文章

  1. java new newinstance_Java中newInstance()和new()区别
  2. 【iOS数据持久化】Plist使用
  3. Convert PLY to VTK Using PCL 1.6.0 or PCL 1.8.0 使用PCL库将PLY格式转为VTK格式
  4. 解决不是有效的win32应用程序
  5. 开源如此火热,但研究表明该领域已不再增长
  6. 划重点!《企业数字化升级之路》白皮书讲了哪些干货?
  7. oracle tochar fm,oracle的to_char中的fm
  8. android 获取文件夹下的所有文件
  9. CPU的高速缓存存储器知识整理
  10. 微软Azure开源开发者(深圳)峰会等你来
  11. lamp配置python_LAMP搭建笔记
  12. python测试脚本截图_Python+selenium实现截图图片并保存截取的图片
  13. 固态和机械硬盘组raid_联想G400拆机步骤(固态硬盘替换机械硬盘,机械硬盘替换光驱)...
  14. 【混凝土强度预测】基于matlab BP神经网络混凝土强度预测【含Matlab源码 695期】
  15. python 导出为csv_批量导出SolidWorks模型点坐标值
  16. python: 产品选型小软件
  17. FYI | Neuro Workshop (Virtual)-Connectomics
  18. 微信小程序 引用 weui 问题合集
  19. PDP上下文和PDP地址
  20. Java之BIO网络编程

热门文章

  1. 【牛客 - 330C】Applese 走迷宫(bfs)
  2. Apollo进阶课程㊱丨Apollo ROS深入介绍
  3. 用OpenSSL编写SSL,TLS程序
  4. html 表格文字颜色 css,CSS 表格-JavaScript中文网-JavaScript教程资源分享门户
  5. c语言学生对老师的评教系统,学生对老师的评价
  6. ip地址合不合法怎么看_到底醇基燃料合不合法呢?
  7. joptionpane java_Java JOptionPane
  8. 如何实现两个数据库之间的同步
  9. java 错误登陆次数_纯java代码实现登陆次数验证,登陆错误5次之后锁定30分钟
  10. leetcode72 编辑距离