**
近日在複習資料結構,看到棧的時候,發現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的鏈結,寫得太詳細了:
n個元素進棧,共有多少種出棧順序?
近日在複習資料結構,看到棧的時候,發現1個元素進棧,有1種出棧順序 2個元素進棧,有2種出棧順序 3個元素進棧,有5種出棧順序,那麼乙個很自然地問題就是n個元素進棧,共有多少種出棧順序?說來慚愧,以前學資料結構的時候竟然沒有考慮過這個問題。最近在看動態規劃,所以 子問題 這3個字一直在我腦中徘徊,於...
n個元素進棧,共有多少種出棧順序?
近日在複習資料結構,看到棧的時候,發現1個元素進棧,有1種出棧順序 2個元素進棧,有2種出棧順序 3個元素進棧,有5種出棧順序,那麼乙個很自然地問題就是n個元素進棧,共有多少種出棧順序?說來慚愧,以前學資料結構的時候竟然沒有考慮過這個問題。最近在看動態規劃,所以 子問題 這3個字一直在我腦中徘徊,於...
n個元素進棧,共有多少種出棧順序?
摘自 1.基於棧的問題分析 我們把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號位置...