出栈顺序 与 卡特兰数(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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cad多段线画圆弧方向_CAD箭头怎么画

CAD箭头怎么画问&#xff1a;CAD箭头怎么画&#xff1f;答&#xff1a;想要回答CAD箭头怎么画这个问题&#xff0c;得先从CAD多段线命令说起&#xff0c;画箭只是多段线的一种应用。执行CAD多段线命令的三种方式1.单击菜单栏上的"绘图">>"多段线"。2…

php 获取delete蚕丝_php结合Redis实现100万用户投票项目,并实时查看到投票情况的案例...

场景&#xff1a;某网站需要对其项目做一个投票系统&#xff0c;投票项目上线后一小时之内预计有100万用户进行投票&#xff0c;希望用户投票完就能看到实时的投票情况这个场景可以使用redismysql冷热数据交换来解决。何为冷热数据交换&#xff1f;冷数据&#xff1a;之前使用的…

硬件内存模型 Hardware Memory Models

硬件内存模型 Hardware Memory Models (Memory Models, Part 1) Posted on Tuesday, June 29, 2021. 简介&#xff1a;童话的终结 很久以前&#xff0c;当人们还在写单线程程序的时候&#xff0c;让程序跑的更快的一个最有效的办法就是什么也不做&#xff0c;因为下一代硬件…

【Go】Map 的空间利用率统计

Go 中 map 利用率 今天刷 B 站看见有 Up 主在讲布隆过滤器&#xff0c;提到了利用率的问题&#xff0c;假设有一组数据&#xff0c;范围分布非常广&#xff0c;使用布隆过滤器时如何尽量少的减少内存使用&#xff0c;感觉除了针对特定数据的定向优化外没什么特别好的办法&…

ap模式和sta模式共存_AP+AC组网下的本地转发及集中转发

现在越来越多的企业都有自己的无线网络&#xff0c;而无线网络的组网方式一般都是使用ACAP模式进行组网&#xff0c;使用无线网络能够提供经济、高效的网络接入方式。相比有线网络&#xff0c;无线网络下只要能接入无线网的地方都可以使用网络&#xff0c;用户可以自由移动。而…

【干货分享】流程DEMO-事务呈批表

流程名&#xff1a; 事务呈批表 业务描述&#xff1a; 办公采购、会议费用等事务的申请。流程发起时&#xff0c;会检查预算&#xff0c;如果预算不够&#xff0c;将不允许发起费用申请&#xff0c;如果预算够用&#xff0c;将发起流程&#xff0c;同时占用相应金额的预算&…

【译】TcMalloc: Thread-Caching Malloc

TcMalloc 的核心是分层缓存&#xff0c;前端没有锁竞争&#xff0c;可以快速分配和释放较小的内存对象&#xff08;一般是 256 KB&#xff09;前端有两种实现&#xff0c;分别是 pre-CPU 和 pre-Thread 模式&#xff0c;前者申请一块大的连续内存&#xff0c;每一个逻辑 CPU 将…

kotlin编译失败_Kotlin使用GraalVM开发原生命令行应用

背景之前用kotlin开发过一款根据建表DDL语句生成plantuml ER图的应用。被问如何使用&#xff0c;答曰"给你一个jar包&#xff0c;然后执行java -jar ddl2plantuml.jar ./ddl.sql ./er.puml 就可以了。是不是so easy?"结果被吐槽了一番&#xff0c;为什么不能像命令行…

Swift - 添加纯净的Alamofire

Swift - 添加纯净的Alamofire 如果你有代码洁癖,不能容忍任何多余的东西,请继续往下看. 1. 下载Alamofire (https://github.com/Alamofire/Alamofire) 2. 解压缩并打开 Alamofire.xcworkspace 3. 删除不必要的内容 (根据你的需求自己定) 4. 顺便把文件夹里面的无关内容也删除掉…

jquery 获取系统默认年份_你没有看错,爬网页数据,C# 也可以像 Jquery 那样

一&#xff1a;背景1. 讲故事前段时间搞了一个地方性民生资讯号&#xff0c;资讯嘛&#xff0c;都是我抄你的&#xff0c;你抄官媒的&#xff0c;小市民都喜欢奇闻异事&#xff0c;所以就存在一个需求&#xff0c;如何去定向抓取奇闻异事的地方号上的新闻&#xff0c;其实做起来…

undertow 怎么创建线程_为什么很多SpringBoot开发者放弃了Tomcat,选择了Undertow

点击上方“后端技术精选”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;作者&#xff1a;阿迈达toutiao.com/a6775476659416990212/前言在SpringBoot框架中&#xff0c;我们使用最多的是Tomcat&#xff0c;这是SpringBoot默认的容器技术&#xff0c;而且是内…

一起玩转CoordinatorLayout

作为Material Design风格的重要组件,CoordinatorLayout协调多种组件的联动&#xff0c;实现各种复杂的效果&#xff0c;在实际项目中扮演着越来越重要的角色。本篇博客将由浅到深&#xff0c;带你一起玩转CoordinatorLayout。 官方文档对CoordinatorLayout是这样描述的&#xf…

离散数学图论旅行规划问题_2020年MathorCup高校数学建模挑战赛——C 题 仓内拣货优化问题...

下面的链接是精华版思路&#xff0c;亮点是对第六问的探讨。高度概括一下&#xff1a;第一问曼哈顿&#xff0c;第二问用免疫&#xff0c;三问增加任务单&#xff0c;四问增加拣货员&#xff0c;五问改变复核台&#xff0c;六问亮点来探讨~ 有点皮MathorCup C题 仓内拣货优化问…

【VBA编程】10.自定义集合

自定义集合类型&#xff0c;类似于变量声明&#xff0c;只是要将Dim关键字和New collection关键字搭配起来使用&#xff0c;其语法描述如下&#xff1a;其中集合名的命名方式同于标准变量的命名 Dim 集合名 As New collection 对于已经定义的集合对象&#xff0c;可以使用集合的…

git fork clone 区别_Working with Git | Git 与 GitHub

关于各位好&#xff0c;这里是 Chinas Prices Project 项目的知乎专栏。关于 CPP 项目&#xff0c;您可以在这篇文章里了解到更多的信息。若您对这个项目感兴趣&#xff0c;我们非常欢迎您与我们交流您的想法与见解。在一个团队的成员同时为一个项目进行开发工作时&#xff0c;…

舒适的路线(codevs 1001)

题目描述 DescriptionZ小镇是一个景色宜人的地方&#xff0c;吸引来自各地的观光客来此旅游观光。Z小镇附近共有N(1<N≤500)个景点&#xff08;编号为1,2,3,…,N&#xff09;&#xff0c;这些景点被M&#xff08;0<M≤5000&#xff09;条道路连接着&#xff0c;所有道路都…

PHP_Smarty

模板 数据与表现层的标签分离 smarty是PHP 与 HTML代码的分离 小型模板类 $smarty 的工作流程&#xff1a; 把需要显示的全局变量&#xff0c;赋值塞到对象内部的属性上&#xff0c;一个数组中.编译模板&#xff0c;把{$标签},解析成相应的<?php echo 代码引入编译后的PHP文…

读中文_挑战来了!康辉喊你读中文十级绕口令!

文章来源&#xff1a;央视频汉语桥木甬读桶不读涌&#xff0c;月农读脓不读胧。米更读粳不读梗&#xff0c;日青读晴不读睛。米宗读粽不读综&#xff0c;言丁读订不读钉。土竟读境不是镜&#xff0c;土平读坪不是评。耳令读聆不读岭&#xff0c;火登读灯不读澄。言甬读诵不读蛹…

ios 自定义键盘

由于项目需要&#xff0c;需要自定义键盘。ios系统键盘会缓存键盘输入&#xff0c;并保存在系统目录下的文件里&#xff0c;并且是明文存储&#xff0c;存在帐号密码泄漏风险。在别人代码基础上修改了下&#xff0c;美化了下界面&#xff0c;去掉了字符输入&#xff0c;加了点击…

【GOF23设计模式】迭代器模式

【GOF23设计模式】迭代器模式 来源&#xff1a;http://www.bjsxt.com/ 一、【GOF23设计模式】_迭代器模式、JDK内置迭代器、内部类迭代器 1 package com.test.iterator;2 /**3 * 自定义的迭代器接口4 */5 public interface MyIterator {6 void first(); //将游标指向第…