[栈] 卡特兰数与入栈出栈序列

假如现在有这么一个问题:

一个序列从1到n依次入栈, 那么可能的出栈序列一共有多少种?
注意: 在任意一个时刻,只要栈不为空, 就可能有元素出栈, 不是说元素全部入栈之后再出栈

这个问题的解其实等同于求n阶的卡特兰数(catalan)

先给出问题的解
设n阶的卡特兰数为k(n), 那么

k(0) = 1, k(1) = 1

k(n) = k(0) * k(n - 1) + k(1) * k(n - 2) + ... + k(n - 2) * k(1) + k(n - 1) * k(0)
或者
k(n) = c(2n, n) / (n + 1)
或者
k(n) = c(2n, n) - c(2n, n-1)

下面是问题的具体分析过程

首先说明为什么问题的解是卡特兰数

卡特兰数指的是在一个n*n的方格中,从左下角走到右上角. 每一步只能往右或者往上, 且在走的过程中不能越过从左下角到右上角的那条对角线.

和入栈出栈问题对比可以发现, 这里的往右走就相当于入栈, 往上走就相当于出栈, 对角线上的点就相当于栈为空的时候, 不能越过对角线就是说在栈为空的时候不能执行弹栈操作

那么卡特兰数如何求得呢, 思路有很多,这里说几种比较容易理解的

1. 用排列组合的方法来求

我们借助栈的思想来理解

n个元素入栈再出栈, 那么就有 2n 次操作, 正常情况下是n次入栈操作, n次出栈操作, 根据排列组合的方法, 共有 c(2n, n) 种可能性

当然了,在这 c(2n, n) 种可能性中, 肯定是有非法操作的, 也就是在在为空或者为负的时候进行出栈操作, 那么非法的情况一共有多少种呢?

我们假设在第一次出现非法操作的时候, 这个时候栈中元素个数为 -1 , 因为在没有元素的时候进行了出栈操作. 由于最终栈中元素数量为 0 , 那么在这一步之后的操作中,入栈次数肯定比出栈次数多 1 . 如果我们对这次操作之后的所有操作进行反转, 那么最终栈中元素的数量就是 -1 减去 1 = -2 了. 这就是非法的情况.

在非法的情况下, 由于最终栈中元素数为-2, 所以在2n次操作中, 肯定有 n - 1 次入栈操作, n + 1 次出栈操作. 这时入栈次数和出栈次数不同是因为我们对部分操作进行了反转, 这一点要明白.

到这里, 答案就很明显了, 非法操作的次数为 c(2n, n -1) = c(2n, n + 1)

所以合法的次数等于所有可能的次数减去非法的次数, 即:

k(n) = c(2n, n) - c(2n, n-1)

2. 折线法

这种方法其实与第一种方法有异曲同工之妙, 只是运用了图形来帮助理解

我们假设一个人在原点,操作1是此人沿右上角45°走一个单位(一个单位设为根号2,这样他第一次进行操作1就刚好走到(1,1)点),操作2是此人沿右下角45°走一个单位。第k次操作2前必须先进行至少k次操作1,就是说明所走出来的折线不能跨越x轴走到y=-1这条线上!在进行n次操作1和n此操作2后,此人必将到到达(2n,0)!若无跨越x轴的限制,折线的种数将为 c(2n,n),即在 2n 次操作中选出n次作为操作1的方法数。

合法情况.jpg

现在只要减去跨越了x轴的情况数。对于任意跨越x轴的情况,必有将与 y = -1相交。找出第一个与 y = -1 相交的点 k,将k点以右的折线根据 y = -1 对称(即操作1与操作2互换了)。可以发现终点最终都会从(2n,0)对称到(2n,-2)。由于对称总是能进行的,且是可逆的。我们可以得出所有跨越了x轴的折线总数是与从(0,0)到(2n,-2)的折线总数。而后者的操作2比操作1要多 0-(-2)=2次。即操作 1 为 n-1 , 操作 2 为 n+1。总数为 c(2n,n-1)。

非法情况.jpg

3. 递归的方法

若用(n,m)表示有n个元素还没有入栈,栈内目前有m个元素时,出栈可能的种数。则问题就是(n,0)。

当目前状态为(n, 0)时只能进行入栈操作,则有(n, 0) = (n - 1, 1)。当m>=1时,可以入栈也可以出栈则有(n, m) = (n - 1, m + 1) + (n, m - 1)。显然(0, m) = 1。这样就有了终止条件。

以上思路可以用递归程序实现

function catalan(n)
{
    return condition(n, 0)
}

/*
 * 递归函数, 用来求特定的某个时刻对应的可能性种数
 *
 * @param total - 还没有入栈的元素的个数
 *
 * @param inStack - 当前栈中元素个数
 *
 */
function condition(outStack, inStack)
{
    if(outStack === 0)
    {
        return 1
    }
    if(inStack === 0)
    {
        return condition(outStack - 1, 1)
    }
    return condition(outStack - 1, inStack + 1) + condition(outStack, inStack - 1)
    // 注意, 这里第二项inStack减少1然而outStack没有加1是因为这个出栈的元素已经不必再考察了, 我们
    // 只需要关注后面的还没有入栈元素即可
}

// 测试

for(let i = 1; i <= 10; i ++)
{
    console.log(`${i}阶卡特兰数为: ${catalan(i)}`)
}

// 1阶卡特兰数为: 1
// 2阶卡特兰数为: 2
// 3阶卡特兰数为: 5
// 4阶卡特兰数为: 14
// 5阶卡特兰数为: 42
// 6阶卡特兰数为: 132
// 7阶卡特兰数为: 429
// 8阶卡特兰数为: 1430
// 9阶卡特兰数为: 4862
// 10阶卡特兰数为: 16796
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容