N個數順序進棧,出棧的情況

2021-06-18 05:15:03 字數 1492 閱讀 4711

近日在複習資料結構,看到棧的時候,發現1個元素進棧,有1種出棧順序;2個元素進棧,有2種出棧順序;3個元素進棧,有5種出棧順序,那麼乙個很自然地問題就是n個元素進棧,共有多少種出棧順序?

說來慚愧,以前學資料結構的時候竟然沒有考慮過這個問題。最近在看動態規劃,所以「子問題」這3個字一直在我腦中徘徊,於是解決這個問題的時候我也是用類似「子問題」的方法,說白了就是遞推公式。

我們把n個元素的出棧個數的記為f(n), 那麼對於1,2,3, 我們很容易得出:

f(1) = 1     

//即 1

f(2) = 2

//即 12、21

f(3) = 5

//即 123、132、213、321、231

然後我們來考慮f(4), 我們給4個元素編號為a,b,c,d, 那麼考慮:元素a只可能出現在1號位置,2號位置,3號位置和4號位置(很容易理解,一共就4個位置,比如abcd,元素a就在1號位置)。

分析:

1) 如果元素a在1號位置,那麼只可能a進棧,馬上出棧,此時還剩元素b、c、d等待操作,就是子問題f(3);

2) 如果元素a在2號位置,那麼一定有乙個元素比a先出棧,即有f(1)種可能順序(只能是b),還剩c、d,即f(2),     根據乘法原理,一共的順序個數為f(1) * f(2);

3) 如果元素a在3號位置,那麼一定有兩個元素比1先出棧,即有f(2)種可能順序(只能是b、c),還剩d,即f(1),

根據乘法原理,一共的順序個數為f(2) * f(1);

4) 如果元素a在4號位置,那麼一定是a先進棧,最後出棧,那麼元素b、c、d的出棧順序即是此小問題的解,即         f(3);

結合所有情況,即f(4) = f(3) + f(2) * f(1) + f(1) * f(2) + f(3);

為了規整化,我們定義f(0) = 1;於是f(4)可以重新寫為:

f(4) = f(0)*f(3) + f(1)*f(2) + f(2) * f(1) + f(3)*f(0)

然後我們推廣到n,推廣思路和n=4時完全一樣,於是我們可以得到:

f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0) 即

但這只是乙個遞推公式(若程式設計實現,需要維護乙個一維陣列,時間複雜度為o(n^2))。怎麼把它轉化為通項公式呢,複雜度僅為o(1)?

於是上網搜尋一下,原來真的有這麼乙個公式:

c(2n,n)/(n+1) (c(2n,n)表示2n裡取n),並且有個名字叫catalan數。附上wiki的鏈結,寫得太詳細了:

update

根據網友u010896627的思路,我抽象了下問題,在知乎上問了個問題,其中有乙個答案提出了「折現法」,從幾何上推出了「n個元素進棧有多少個出棧順序」這個問題的答案是c(2n,n)-c(2n,n-1),化簡一下即得catalan number。推薦大家看一看。

n個元素進棧,出棧順序問題

近日在複習資料結構,看到棧的時候,發現1個元素進棧,有1種出棧順序 2個元素進棧,有2種出棧順序 3個元素進棧,有5種出棧順序,那麼乙個很自然地問題就是n個元素進棧,共有多少種出棧順序?說來慚愧,以前學資料結構的時候竟然沒有考慮過這個問題。最近在看動態規劃,所以 子問題 這3個字一直在我腦中徘徊,於...

n個數順序入棧後的出棧順序

解法 遞推法 有n個位置,現在任意選定乙個數,比如1,那麼1可以在1 n的任意乙個位置上。假設1在第k的位置上,顯然在1的前面有k 1個數,並且這些數的數值為2 k,在1後面有n k個數。用f k 表示k個數順序入棧後的出棧順序,則f n 就是我們要求的最終答案。而f n 這個事件又可以分解成1在1...

n個元素進棧,共有多少種出棧順序?

近日在複習資料結構,看到棧的時候,發現1個元素進棧,有1種出棧順序 2個元素進棧,有2種出棧順序 3個元素進棧,有5種出棧順序,那麼乙個很自然地問題就是n個元素進棧,共有多少種出棧順序?說來慚愧,以前學資料結構的時候竟然沒有考慮過這個問題。最近在看動態規劃,所以 子問題 這3個字一直在我腦中徘徊,於...