堆栈出栈顺序个数详解——卡兰特数

  参考了多篇博客之后,终于弄懂了,写下了方便以后复习!首先简单介绍一下堆栈的运行方式,先入后出,First In Last Out(FILO),即若我们将1-4顺序放入堆栈中,则出栈顺序为4 3 2 1。了解堆栈的出栈顺序后,接下来介绍一下若将1-n顺序放入堆栈中,可能的出栈情况个数。本文将介绍两种方法,第一种通过01字符串考虑,第二种通过利用组合数学,考虑数字1的出栈所在位置进行分析。

01字符串

考虑以下的情况:
  *
  * *
  * * *
  * * * *
  上述的三角形方针表示只能向下走或向右走,(向下走表示入栈,向右走表示出栈),那上述的三角形方针就表示123可能的出栈顺序。下面的图就表示出栈顺序为231。
堆栈出栈顺序个数详解——卡兰特数_第1张图片
  如果用1表示入栈,0表示出栈,则1-n的入栈与出栈顺序就可由2n个01字符串表示。那所有情况就是C(n,2n),当然里面包含许多不满足堆栈实际情况的出入栈顺序。
  由上述三角形方针可知,如果出栈个数多于入栈个数的话是不可能存在的情况,我们上述举的例子出栈顺序为231的话,整体用01表示为110100(1入栈,2入栈,2出栈,3入栈,3出栈,1出栈),那假设01串为100110的话肯定是不可能的,入栈才1个数,出栈就两个数了,通过这个例子可以明白为何出栈个数多于入栈个数的话是不可能存在的,即0的个数大于1的个数。下面来分析这种不满足情况的有多少种:
  已知整个01数字串中包含n个0,n个1。在第一次出现0的个数比1的个数多时,假设1出现了k次,0出现了k+1次,则之后的01序列中1的个数为n-k,0的个数为n-k-1,若将后半部分的0换成1,1替换成0,则总体的数字串包含1有k+n-k-1=n-1个,同理0的个数有n+1个。那就可以求出来不满足情况的有C(n+1,2n)个。

  因此,若将1-n顺序放入堆栈中,共有情况C(n,2n)-C(n+1,2n)种。

利用组合数学

  假设数字1在出栈顺序中占第k位(从第一位开始),则数字1之前包含k-1个数字,1之后包含n-k个数字,且数字1之前出现的数字一定为2-k,数字1之后出现的数字为k+1到n。如图所示:
堆栈出栈顺序个数详解——卡兰特数_第2张图片
  数字1入栈后,数字2-k以某种顺序入栈并出栈,之后数字1出栈,(满足假设在第k位出栈),之后数字k+1到n以某种顺序入栈并出栈。数字2-k以某种顺序入栈并出栈的情况种数为f(k-1),数字k+1到n以某种顺序入栈并出栈的情况种数为f(n-k),因此由乘法原理可知,数字1在第k位出栈的情况种数为f(k-1)·f(n-k)
  数字1又可能出现在第1位,第2位,第3位,…,第k位,…,第n位。

  • 出现在第1位的情况总数为f(0)·f(n-1)
  • 出现在第2位的情况总数为f(1)·f(n-2)
  • 出现在第3位的情况总数为f(2)·f(n-3)
  • 出现在第k位的情况总数为f(k-1)·f(n-k);
  • 出现在第n位的情况总数为f(n-1)·f(0);

因此总的可能个数为f(0)·f(n-1)+f(1)·f(n-2)+f(2)·f(n-3)+…+f(k-1)·f(n-k)+f(n-1)·f(0)。这个就是卡兰特数了,最后结果f(n) = C(n,2n)-C(n+1,2n)

你可能感兴趣的:(堆栈出栈顺序个数详解——卡兰特数)