出棧順序 與 卡特蘭數(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.pswp.cn/news/457384.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457384.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457384.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[譯] Bounds Check Elimination 邊界檢查消除

[譯] Bounds Check Elimination 邊界檢查消除 Go 是一種內存安全的語言&#xff0c;在針對數組 (array) 或 Slice 做索引和切片操作時&#xff0c;Go 的運行時&#xff08;runtime&#xff09;會檢查所涉及的索引是否超出范圍。如果索引超出范圍&#xff0c;將產生一個 Panic&…

cad多段線畫圓弧方向_CAD箭頭怎么畫

CAD箭頭怎么畫問&#xff1a;CAD箭頭怎么畫&#xff1f;答&#xff1a;想要回答CAD箭頭怎么畫這個問題&#xff0c;得先從CAD多段線命令說起&#xff0c;畫箭只是多段線的一種應用。執行CAD多段線命令的三種方式1.單擊菜單欄上的"繪圖">>"多段線"。2…

HDU 5410 CRB and His Birthday ——(完全背包變形)

對于每個物品&#xff0c;如果購買&#xff0c;價值為A[i]*xB[i]的背包問題。 先寫了一發是WA的 。代碼如下&#xff1a; 1 #include <stdio.h>2 #include <algorithm>3 #include <string.h>4 #include <set>5 using namespace std;6 typedef pair<…

一篇講Java指令重排和內存可見性的好文

在這里&#xff1a; http://tech.meituan.com/java-memory-reordering.html 指令重排和內存可見性&#xff08;緩存不一致&#xff09;是兩個不同的問題。 volatile關鍵字太強&#xff0c;即阻擋指令重排&#xff0c;又保證內存一致性。 unsafe.putOrderedXXX()只阻擋指令重排&…

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;因為下一代硬件…

碰到日期題就怕的我來寫一道水題吧

HDOJ-2005&#xff0c; http://acm.hdu.edu.cn/showproblem.php?pid2005 20XX系列的水題哈哈&#xff0c;寫了二十分鐘&#xff0c;就為找到一種比較正常不傻逼的寫法。。。 嗯&#xff0c;學習了一下&#xff0c;閏年的判斷可以寫成一個接受參數的宏。 #define lev(n) (n%40&…

判斷是否為gif/png圖片的正確姿勢

判斷是否為gif/png圖片的正確姿勢 1.在能取到圖片后綴的前提下 123456789//假設這是一個網絡獲取的URLNSString *path "http://pic3.nipic.com/20090709/2893198_075124038_2.gif";// 判斷是否為gifNSString *extensionName path.pathExtension;if ([extensionName…

【Go】Map 的空間利用率統計

Go 中 map 利用率 今天刷 B 站看見有 Up 主在講布隆過濾器&#xff0c;提到了利用率的問題&#xff0c;假設有一組數據&#xff0c;范圍分布非常廣&#xff0c;使用布隆過濾器時如何盡量少的減少內存使用&#xff0c;感覺除了針對特定數據的定向優化外沒什么特別好的辦法&…

ap模式和sta模式共存_AP+AC組網下的本地轉發及集中轉發

現在越來越多的企業都有自己的無線網絡&#xff0c;而無線網絡的組網方式一般都是使用ACAP模式進行組網&#xff0c;使用無線網絡能夠提供經濟、高效的網絡接入方式。相比有線網絡&#xff0c;無線網絡下只要能接入無線網的地方都可以使用網絡&#xff0c;用戶可以自由移動。而…

《JS權威指南學習總結--6.7屬性的特性》

內容要點&#xff1a; 一.ES5中查詢和設置屬性的API 1.可以通過這些API給原型對象添加方法&#xff0c;并將它們設置成不可枚舉的&#xff0c;這讓它們看起來更像內置方法。 2.可以通過這些API給對象定義不能修改或刪除的屬性&#xff0c;借此 "鎖定" 這個對象。 3.數…

【干貨分享】流程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;其實做起來…

linux下怎么編譯運行C語言程序?

linux下的C語言編譯器是gcc&#xff0c;C的編譯器是g。 linux下編程可以使用編輯器vi或vim&#xff0c;建議使用vim&#xff0c;因為它有語法高亮顯示。程序編寫好后&#xff0c;假設你的程序名為test.c&#xff0c;可以使用gcc -o test test.c。test就是編譯好的可執行程序./t…

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題 倉內揀貨優化問…