出栈顺序 与 卡特兰数(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,且这个顺序是递减顺序。同样地,对于数字 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)的关系相关推荐
- 堆栈出栈顺序个数详解——卡兰特数
参考了多篇博客之后,终于弄懂了,写下了方便以后复习!首先简单介绍一下堆栈的运行方式,先入后出,First In Last Out(FILO),即若我们将1-4顺序放入堆栈中,则出栈顺序为4 3 2 ...
- 卡特兰数 Catalan number
卡特兰数 Catalan number 卡特兰数前几项为 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 74290 ...
- n个元素进栈,共有多少种出栈顺序?
1.基于栈的问题分析 我们把n个元素的出栈个数的记为f(n), 那么对于1,2,3, 我们很容易得出: f(1) = 1 //即 1 f(2) = 2 //即 12.21 f(3) = ...
- 算法基础 - 数论 | 组合数学 卡特兰数(Catalan number)定义、证明及例题
写在前面:卡特兰数这东西感觉挺常用的,并且公式很简单,那就花一下午总结一下,学点皮毛吧(反正遇到我还是不会 ) [PDF] 大三上组合数学课堂讲义 文章目录 卡特兰数定义 卡特兰数的性质 卡特兰数证明 ...
- 元素入栈顺序确定,共有多少种出栈顺序?----Python
文章目录 问题描述 对栈的理解 题目的思考 python代码 卡特兰数 扩展思路 问题描述 前几天看到一个题目,假设五个元素的入栈顺序为e1.e2.e3.e4.e5,那么共有多少种出栈顺序?一时之间思 ...
- 卡特兰数[catalan数]`
定义: 卡特兰数又叫卡塔兰数,是组合数学中一类常用的数列.前几项为:1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 74290 ...
- 出栈顺序问题讲解 蓝桥杯
引言:最近刷数据结构的题,刷到一组元素入栈,他的出栈顺序有可能是哪些时卡住,之前没有关注此类问题,便写下总结 先通过几个例题讲解下出栈顺序问题 1. 一个栈的入栈序列是a,b,c,d,e则栈的不可能的 ...
- 卡特兰数Catalan Number
Catalan Number满足下列递推公式: N个元素元素进栈,多少种出栈方式 考虑A.B.C.D依次进栈,那么所有的出栈顺序是下列4种情况的并集: 1)A第一个出栈.肯定是A进栈后马上出栈,剩下B ...
- 数据结构----出栈顺序有效性的判断
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. ...
最新文章
- java new newinstance_Java中newInstance()和new()区别
- 【iOS数据持久化】Plist使用
- Convert PLY to VTK Using PCL 1.6.0 or PCL 1.8.0 使用PCL库将PLY格式转为VTK格式
- 解决不是有效的win32应用程序
- 开源如此火热,但研究表明该领域已不再增长
- 划重点!《企业数字化升级之路》白皮书讲了哪些干货?
- oracle tochar fm,oracle的to_char中的fm
- android 获取文件夹下的所有文件
- CPU的高速缓存存储器知识整理
- 微软Azure开源开发者(深圳)峰会等你来
- lamp配置python_LAMP搭建笔记
- python测试脚本截图_Python+selenium实现截图图片并保存截取的图片
- 固态和机械硬盘组raid_联想G400拆机步骤(固态硬盘替换机械硬盘,机械硬盘替换光驱)...
- 【混凝土强度预测】基于matlab BP神经网络混凝土强度预测【含Matlab源码 695期】
- python 导出为csv_批量导出SolidWorks模型点坐标值
- python: 产品选型小软件
- FYI | Neuro Workshop (Virtual)-Connectomics
- 微信小程序 引用 weui 问题合集
- PDP上下文和PDP地址
- Java之BIO网络编程
热门文章
- 【牛客 - 330C】Applese 走迷宫(bfs)
- Apollo进阶课程㊱丨Apollo ROS深入介绍
- 用OpenSSL编写SSL,TLS程序
- html 表格文字颜色 css,CSS 表格-JavaScript中文网-JavaScript教程资源分享门户
- c语言学生对老师的评教系统,学生对老师的评价
- ip地址合不合法怎么看_到底醇基燃料合不合法呢?
- joptionpane java_Java JOptionPane
- 如何实现两个数据库之间的同步
- java 错误登陆次数_纯java代码实现登陆次数验证,登陆错误5次之后锁定30分钟
- leetcode72 编辑距离