首页 > 其他分享 >已知n个数的入栈序列,求一共有多少种出栈序列 (卡特兰数)

已知n个数的入栈序列,求一共有多少种出栈序列 (卡特兰数)

时间:2023-04-23 17:58:25浏览次数:44  
标签:出栈 入栈 个数 取反 合法 序列 2n 卡特兰

已知\(n\)个数的入栈序列,求一共有多少种出栈序列

这个经典问题有两种解法。

解法一:

设\(f(x)\)为\(x\)个数入栈后,再全部出栈的序列数量

假设我们有\(4\)个数\(a,b,c,d\), 我们来看\(a\)的出栈顺序.

假如\(a\)第一个出栈,那么后面还有\(3\)个数没有出栈,因此方法数是\(f(3)\).

假设\(a\)第二个出栈,那么\(a\)的前面有\(1\)个数已经出栈,后面还有\(2\)个数没有出栈,因此方法数为\(f(1) * f(2)\).

假设\(a\)第三个出栈,那么\(a\)的前面有\(2\)个数已经出栈,后面还有\(1\)个数没有出栈,因此方法数为\(f(2) * f(1)\).

同理,\(a\)第四个出栈的方法数为\(f(3)\).

那么我们就可以得到\(f(4) = f(3) + f(1) *f(2) + f(2)*f(1) +f(3)\).

对于\(n\)来推广一下,可以得到:\(f(n)=\sum_{i=1}^{n}f(i - 1)*f(n-i)\).

不难发现这就是卡特兰数,这里就不在赘述了。

解法二:

我们假设\(-1\)表示出栈,\(1\)表示入栈,这样我们就可以用\(-1\)和\(1\)组成的序列来表示出入栈操作。

首先来限定一些条件,一个合法的序列\(0\)和\(1\)的数量一定是相等的。并且序列的前缀和一定是不小于\(0\)的。

了解了上面两个条件后,我们知道所有的序列数为\(C^{\ n}_{2n}\),因为\(-1\)和\(1\)的数量相同。在这\(C^{\ n}_{2n}\)个序列中,存在不合法的序列,即前缀和小于\(0\)的序列,我们想要知道这些不合法的序列有多少。

假设我们有一个序列\(1,-1,-1,1,-1,1\),这里在第三个下标,我们发现了它的前缀和小于\(0\),因此它不合法。再来推广一下,在这所有\(C^{\ n}_{2n}\)个序列中,不合法的序列它的前缀和一定在某一处小于\(0\).

接下来,我们将序列开头到不合法下标的这一段进行取反。首先拿上面的例子来进行说明,取反后得到:\(-1,1,1,1,-1,1\),不难发现,现在得到的序列\(+1\)比\(-1\)多出一个.

现在再来进行推广,我们截取的不合法序列段(从开头到不合法前缀和下标),这一段中的\(-1\)一定比\(+1\)多一个,那么将这一段取反后所得到的总序列中的\(+1\)一定比\(-1\)多一个。

不难发现,不合法的序列一定对应唯一一个取反后的序列,并且取反后的序列中\(+1\)有\(n+1\)个,\(-1\)有\(n-1\)个,那么根据这个条件,我们就可以得到所有不合法的序列数量为\(C_{2n}^{n+1}\)或者\(C^{n-1}_{2n}\)(因为他两相等)。

最后,合法的序列数为:\(C^{\ n}_{2n}-C_{2n}^{n+1\ or\ n-1}\).

这个解法的关键在于,不合法的序列一定唯一对应一个取反后的序列,那么我们可以算出所有取反后的数列有多少种(根据\(+1\)有\(n+1\)个,\(-1\)有\(n-1\)个的性质),来对应出不合法的序列数,从而得到答案.

因为感觉这种解法非常的巧妙,因此想写篇博客来总结一下.

标签:出栈,入栈,个数,取反,合法,序列,2n,卡特兰
From: https://www.cnblogs.com/lr599909928/p/17347276.html

相关文章

  • 时间序列预测相关技术的实现构建
    1.构建数据库2.掌握基于机器学习的基本方案3.搭建并使用机器学习的应用平台 1.构建数据库 时间序列专门的数据库InfluxDBhttps://docs.influxdata.com/influxdb/v2.7/时间序列数据平台,开发人员可以在该平台上构建物联网、分析和云应用程序。    ......
  • rpc学习--替换rpc序列化协议为json
    rpc概念:RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。示例代码:packagemainimport("encoding/json""log""net"......
  • 02 | 产生0,1,2...的序列大致有几种方法
    1.写死的for循环2.生成序列和打印序列分开(占据极大的内存)3.用static来实现(缺点:引入了全局的状态)4.用类来实现(缺点:编写类定义太麻烦)5.使用lambda闭包init6.使用协程注意,此处的协程类是需要自己的实现的。......
  • 剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)
    (剑指Offer33.二叉搜索树的后序遍历序列(java解题))1.题目输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:5/\26/\13示......
  • 剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)
    目录1.题目2.解题思路3.数据类型功能函数总结4.java代码5.踩坑小记递归调用,显示StackOverflowError1.题目输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。参考以下这颗二叉......
  • 20-4-21--链表--两个有序链表序列的合并
    已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。输入格式:输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。输出格式:在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不......
  • 34-同步时序电路设计步骤及序列检测器设计
    同步时序电路设计同步触发器翻转时间一致1.同步时序电路设计的一般步骤1.根据问题描述,确定原始的状态图或者是状态表2.状态化简,状态表中等效的可以合并3.状态分配,触发器的个数,状态如何分配,怎么将一组二进制数赋予不同的状态4.选择触发器(D,JK)5.确定激励方程组以及输......
  • 【DP】LeetCode 1143. 最长公共子序列
    题目链接1143.最长公共子序列思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数组的动态规划问题中,一般dp[i]都是表示以nums以前i个元素组成(即nums[i-1])的状态;dp[i][j]分别表示以nums1前i个元素......
  • P1241 括号序列
    题目描述定义如下规则:空串是「平衡括号序列」若字符串\(S\)是「平衡括号序列」,那么\(\texttt{[}S\texttt]\)和\(\texttt{(}S\texttt)\)也都是「平衡括号序列」若字符串\(A\)和\(B\)都是「平衡括号序列」,那么\(AB\)(两字符串拼接起来)也是「平衡括号序列」。例如,下......
  • .Net 序列化
    .Net序列化将实体转化为流的形式,传递给他人。他人再反序列化就可以得到实体二进制已弃用,存在危险vartbLabel=newDataTable("tbLabel");varms=newMemoryStream();tbLabel.Columns.Add("cWorkOrder");tbLabel.Rows.Add(new[]{"123"});BinaryFormattera1......