PTA(栈和队列)2-6 出栈序列的合法性
PTA(栈和队列)2-6 出栈序列的合法性
zhangzhang2-6 出栈序列的合法性
分数 6
作者 陈越
单位 浙江大学
给定一个最大容量为 m 的堆栈,将 n 个数字按 1, 2, 3, …, n 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 m=5、n=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。
输入格式:
输入第一行给出 3 个不超过 1000 的正整数:m(堆栈最大容量)、n(入栈元素个数)、k(待检查的出栈序列个数)。最后 k 行,每行给出 n 个数字的出栈序列。所有同行数字以空格间隔。
输出格式:
对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES,否则输出NO。
输入样例:
1 | 5 7 5 |
输出样例:
1 | YES |
我的卡壳代码
1 |
|
思路方向是对的(通过记录元素是否出栈、控制入栈顺序来验证),但具体实现时陷入了细节误区,导致逻辑卡住。问题的核心在于:不需要记录 “是否出栈”,而是通过模拟 “入栈→对比出栈元素→出栈” 的完整过程,同时检查栈的容量是否超限。
为什么我的思路容易混乱?
hasOut数组其实是多余的:因为入栈顺序是固定的(1→2→…→n),出栈序列的合法性只取决于 “入栈和出栈的时机”,不需要额外记录是否出栈。- 内层循环逻辑不清晰:遇到当前出栈元素
num时,正确的做法是 “把所有比num小且未入栈的元素先入栈”,再判断栈顶是否等于num并出栈。
正确思路(模拟栈操作)
- 初始化:准备一个栈,以及一个指针
current记录 “下一个要入栈的元素”(从 1 开始)。 - 遍历出栈序列:对每个待检查的序列,逐个处理元素num:
- 先把所有 小于等于
num且未入栈 的元素入栈(即current到num之间的元素)。 - 入栈过程中如果栈的大小超过
m,说明序列不合法。 - 入栈完成后,若栈顶元素等于
num,则出栈;否则序列不合法。
- 先把所有 小于等于
- 最终判断:如果所有元素都能按上述规则处理完,则序列合法(输出 YES),否则不合法(输出 NO)。
正确代码
1 |
|
关键逻辑解析
- 入栈控制:比如当前出栈元素是
3,则必须先把1、2、3依次入栈(因为入栈顺序固定),才能让3出栈。 - 容量检查:入栈时如果栈的大小超过
m(比如m=5,但需要入栈 6 个元素才能匹配出栈序列),则直接判定为非法。 - 栈顶匹配:入栈后栈顶必须等于当前出栈元素,否则说明出栈顺序违反了栈的 “后进先出” 规则(比如出栈序列是
3、1,入栈1、2、3后栈顶是3,出栈后栈顶是2,无法匹配1,故非法)。
示例验证(以输入样例为例)
- 序列
7 6 5 4 3 2 1:需要先入栈1-7,但栈容量m=5,入栈到第 5 个元素时栈已满,无法继续入栈,故输出NO。 - 序列
1 7 6 5 4 3 2:第一个元素1出栈后,需要入栈2-7(共 6 个元素),超过m=5,故输出NO。


