1. 程式人生 > >n個元素進棧,出棧順序問題

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

近日在複習資料結構,看到棧的時候,發現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)