演算法篇:神奇的卡塔蘭數Catalan
阿新 • • 發佈:2019-01-26
這段時間複習資料結構,想起來這神奇的卡塔蘭數
1.百科簡介
卡塔蘭數的來歷:卡特蘭數又稱卡塔蘭數,是組合數學中一個常出現在各種計數問題中出現的數列。由以比利時的數學家歐仁·查理·卡塔蘭 (1814–1894)命名。
2.Catalan數的遞推規律
3.Catalan數相關的問題解答
3.1.給定整數N,輸出所有匹配的小括號序列。
例如:N=3
輸出:
((()))(()())
(())()
()(())
()()()
public static void brackets(int openStock, int closeStock, String s) { if (openStock == 0 && closeStock == 0) {//當開括號的資料和比括號的數目都為零時 System.out.println(s); } //如果開括號數大於0,那麼就新增一個開括號,開括號的數目-1,閉括號的數目+1 if (openStock > 0) { brackets(openStock-1, closeStock+1, s + "("); } //如果閉括號的數目大於0,那麼就新增一個閉括號,閉括號的數目-1 if (closeStock > 0) { brackets(openStock, closeStock-1, s + ")"); } }
呼叫:brackets(3,0,"");
2.所有可能的出棧序列
一個棧(無窮大)的進棧序列為1,2,3,…,n,有多少個不同的出棧序列。
例如:入棧序列為123,則出棧序列有:
321
231
213
132
123
package edu.njupt.zhb; import java.util.Stack; public class TestStackOut { private Stack<String> list = new Stack<String>();//待裝入棧的序列,也用棧來實現 private Stack<String> stack = new Stack<String>();//輔助棧 private StringBuffer out = new StringBuffer();//輸出串 public void popStackOrder(){//遞迴方法 if(stack.empty() && list.empty()){//棧空,序列也空,則輸出 System.out.println(out); return; } if(!list.empty()){//將list棧中的元素轉移到stack String str = list.pop(); stack.push(str); popStackOrder(); str = stack.pop();//復原 list.push(str);//恢復棧 } if(!stack.empty()){// String str = stack.pop();//出棧 out.append(str);//記錄出棧順序 popStackOrder(); out.deleteCharAt(out.length()-1);//復原記錄次序 stack.push(str);//復原 } } public void test(){ //注意,假設入棧序列是123,倒序裝入list棧 list.push("3"); list.push("2"); list.push("1"); popStackOrder(); } public static void main(String[] args) { new TestStackOut().test(); } }
類似的邏輯題還有:
電影院買票問題:
有2n個人排隊進電影院,票價是50美分。在這2n個人當中,其中n個人只有50美分,另外n個人有1美元(紙票子)。愚蠢的電影院開始賣票時1分錢也沒有。問:有多少種排隊方法使得每當一個擁有1美元買票時,電影院都有50美分找錢
注:1美元=100美分擁有1美元的人,擁有的是紙幣,沒法破成2個50美分
解答:很顯然結果是卡塔蘭數,這個和小括號問題很像。
更多Catalan數相關的問題可以參考:
[1]Catalan數解決的常見問題:http://blog.csdn.net/duanruibupt/article/details/6869431