出棧序列的求解方法


卡特蘭數的概念

假如現在有這么一個問題:

一個序列從1到n依次入棧,那么可能的出棧序列一共有多少種?

注意:在任意一個時刻,只要棧不為空,就可能有元素出棧,不是說元素全部入棧之后再出棧。

這個問題的解其實等同於求n階的卡特蘭數(catalan)

卡特蘭數指的是在一個n*n的方格中,從左下角走到右上角。每一步只能往右或者往上,且在走的過程中不能越過從左下角到右上角的那條對角線。

和入棧出棧問題對比可以發現,這里的往右走就相當於入棧,往上走就相當於出棧,對角線上的點就相當於棧為空的時候, 不能越過對角線就是說在棧為空的時候不能執行彈棧操作。

出棧序列的求解方法

既然往右相當於入棧, 往上相當於出棧,那么從左下角到右上角的路徑即為對應的入棧出棧操作序列,我們可以執行全部的操作序列來獲取全部的出棧序列。所以求解出棧序列的個數,只需求出搜索路徑有多少個。

當棧深度為4時,所有可能的搜索路徑(入棧出棧操作序列):

那么搜索又要如何實現?

首先合理的搜索需要滿足兩個前提:

  • 每一步只能往右或者往上
  • 且在走的過程中不能越過從左下角到右上角的那條對角線

搜索的遞歸實現:

  • 從某點開始的后續搜索,可以由其上方點的后續搜索和其右方點的后續搜索組成。
#include <stdio.h>
#include <stdlib.h>

void catalan(int push, int pop, int n, char *order) {
    int index = push + pop;
    if (push == pop && pop == n) {
        order[index] = '\0';
        printf("%s\n", order);
    }
    if (push < n) {
        order[index] = 'i';
        catalan(push + 1, pop, n, order);
    }
    if (pop < push) {
        order[index] = 'o';
        catalan(push, pop + 1, n, order);
    }
}

int main() {
    // n個數入棧
    int n;
    scanf("%d", &n);
    // 入棧出棧操作序列長為2n;
    char *order = calloc(2 * n + 1, sizeof(char));
    // 輸出所有的入棧出棧操作序列
    catalan(0, 0, n, order);
    free(order);
    return EXIT_SUCCESS;
}

參考鏈接

[1] https://www.jianshu.com/p/7d3604dfb8ba


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM