【轉】【數據結構】【有n個元素依次進棧,則出棧序列有多少種】

卡特蘭數編程

大神解釋:https://blog.csdn.net/akenseren/article/details/82149145      權侵刪數組

 

原題

有一個容量足夠大的棧,n個元素以必定的順序入棧,出棧順序有多少種?spa

好比,AB兩個元素,入棧順序爲AB,出棧狀況有兩種:.net

(1)入A,出A,入B,出B,出棧順序爲AB;blog

(2)入A,入B,出B,出A,出棧順序爲BA。遞歸

所以,2個元素時,結果爲2。class

 

分析:設f(n)爲「n個元素以必定的順序入棧,出棧順序的種類數」。顯然f(1)=1,f(2)=2。咱們如今來分析通常狀況。通常狀況下,咱們能夠按照「第一個入棧的元素,在出棧序列中的位置」做爲分類手段。原理

舉個例子,咱們假設入棧元素爲A,B,C,D。咱們按照「A在出棧序列中的位置」分類討論:hack

(1)當A第一個出棧時,A先進,而後立刻出棧。這種狀況下,共有「BCD出棧順序的種類數」種方案。也就是f(n-1)。方法

(2)當A第二個出棧時,A先進,B再進,以後B須要立刻出來(這樣才能確保A排第二)。此時共有f(n-2)種方案。

(3)當A第三個出棧時,A先進,以後只要確保排在A後面兩個的元素比A先出便可。此時共有f(2)*f(n-3)種方案。f(2)是指「BC入棧出棧順序的種類數」,f(n-3)是指」D入棧出棧的種類數」。

……

分析到這裏,規律就很顯然了。

從第一項開始,分別是第一個入棧元素在第i+1個出棧的狀況數。

上式中,令f(0)=1 。

這個其實是卡特蘭數(Catalan number,又稱卡塔蘭數)。

若編程實現,須要維護一個一維數組,時間複雜度爲O(n^2)。(遞歸實現的時間複雜度過高)。

卡塔蘭數的通項公式爲h(n)=C(2n,n)-C(2n,n+1)(n=0,1,2,...)。

 

元素A、B、C、D依次進棧,寫出全部可能的出棧序列

應該有14種狀況
A第一個出棧:ABCD;ACBD;ACDB;ABDC;ADCB;

A第二個出棧:BACD;BADC;

A第三個出棧:CBAD;BCAD;

A第四個出棧:BCDA;CBDA;CDBA;BDCA;DCBA.


卡特蘭數

  卡特蘭數前幾項爲 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...

 令h(0)=1,h(1)=1,catalan數知足遞推式:  h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)

例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2  

h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5  

 

另類遞推式:  h(n)=h(n-1)*(4*n-2)/(n+1);  

遞推關係的解爲:  h(n)=C(2n,n)/(n+1) (n=1,2,3,...)  

遞推關係的另類解爲:  h(n)=c(2n,n)-c(2n,n+1)(n=1,2,3,...)

 

本題目的常規分析

首先,咱們設f(n)=序列個數爲n的出棧序列種數。同時,咱們假定第一個出棧的序數是k。  

第一個出棧的序數k將1~n的序列分紅兩個序列,其中一個是1~k-1,序列個數爲k-1,另一個是k+1~n,序列個數是n-k。  

此時,咱們若把k視爲肯定一個序數,那麼根據乘法原理,f(n)的問題就等價於——序列個數爲k-1的出棧序列種數乘以序列個數爲n - k的出棧序列種數,即選擇k這個序數的f(n)=f(k-1)×f(n-k)而k能夠選1到n,因此再根據加法原理,將k取不一樣值的序列種數相加,獲得的總序列種數爲:f(n)=f(0)f(n-1)+f(1)f(n-2)+……+f(n-1)f(0)。  

看到此處,再看看卡特蘭數的遞推式,答案不言而喻,即爲f(n)=h(n)= C(2n,n)/(n+1)= c(2n,n)-c(2n,n+1)(n=1,2,3,……)。  

最後,令f(0)=1,f(1)=1。 

 

很是規分析

問題等價於:n個1和n個0組成一2n位的2進制數,要求從左到右掃描,1的累計數不小於0的累計數,試求知足這條件的數有多少?【對於每個數來講,必須進棧一次、出棧一次。咱們把進棧設爲狀態‘1’,出棧設爲狀態‘0’】
解答: 設P2n爲這樣所得的數的個數。在2n位上填入n個1的方案數爲 C(n 2n)
不填1的其他n位自動填以數0。從C(n 2n)中減去不符合要求的方案數即爲所求。
不合要求的數指的是從左而右掃描,出現0的累計數超過1的累計數的數。

不合要求的數的特徵是從左而右掃描時,必然在某一奇數2m+1位上首先出現m+1個的累計數,和m個1的累計數。
此後的2(n-m)-1位上有n-m個1,n-m-1個0。如若把後面這部分2(n-m)-1位,0與1交換【就是0換成1 1換成0 不是順序的調換 是數值換】,使之成爲n-m個0,n-m-1個1,結果得 1個由n+1個0和n-1個1組成的2n位數,即一個不合要求的數對應於一個由n-1個0和n+1個1組成的一個排列。

 

咱們把進棧設爲狀態‘1’,出棧設爲狀態‘0’。【對於每個數來講,必須進棧一次、出棧一次】
因爲任意時刻,出棧的操做數必定不超過入棧的操做數

 

不符合要求的數的特徵是由左而右掃描時,必然在某一奇數位2m+1位上首先出現m+1個0的累計數和m個1的累計數,
【出棧數已經大於入棧數了】【由於合法的排列 不管在哪一個位置 1都是>=0的】【前面m個位置0、1排列無論怎麼排列都已經不合法)】
此後的2(n-m)-1位上有n-m個1和n-m-1個0。如若把後面這2(n-m)-1位上的0和1互換,使之成爲n-m個0和n-m-1個1,
結果得1個由n+1個0和n-1個1組成的2n位數,即一個不合要求的數對應於一個由n+1個0和n-1個1組成的排列。
卡特蘭數 爲何要0 1 互換?【互換後的排列中0比1多1個,那麼無論怎麼排列,也都不合法】

 

 

 相似問題 買票找零

1.有2n我的排成一行進入劇場。入場費5元。其中只有n我的有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人買票,售票處就有5元的鈔票找零?(將持5元者到達視做將5元入棧,持10元者到達視做使棧中某5元出棧)

最終結果:C(2n,n)-C(2n,n+1)

2.

*
* *
* * *
* * * *
* * * * *
形如這樣的直角三角形網格,從左上角開始,只能向右走和向下走,問總共有多少種走法?
問題的由來:編號爲 1 到 n 的 n 個元素,順序的進入一個棧,則可能的出棧序列有多少種?
對問題的轉化與思考:n 個元素進棧和出棧,總共要經歷 n 次進棧和 n 次出棧。這就至關於對這 2n 步操做進行排列。
一個模型:一個 n*n 的正方形網格,從左上角頂點到右下角頂點,只能向右走和向下走。問共有多少種走法。若是將向右走對應上述問題的出棧,向下走對應上述問題的進棧,那麼,可 以視此模型爲對上述問題的具體描述。而解決此問題,只要在總共從左上角到右下角的2n步中,選定向右走的步數,即共有C(n 2n)種走法。
可是存在一個問題,若是走法越過了對角線,那麼對應到上述問題是出棧數比入棧數多,這是不符合實際的。
對以上模型進行處理,對角線將以上正方形網格分紅兩部分,只留下包含對角線在內的下半部分,那麼就不會出現越過對角線的問題。而這問題就是開始提出的問題。
 
3.在圓上選擇2n個點,將這些點成對鏈接起來使得所獲得的n條線段不相交的方法數?
https://blog.csdn.net/hackbuteer1/article/details/7450250 沒懂
相關文章
相關標籤/搜索