栈的压入与弹出序列校验

开发 前端
仔细分析题目后,我们很直观的想法就是构造一个辅助栈,把压入序列中的数字依次压入该辅助栈。按照弹出序列的顺序依次从该栈中弹出数字,如果辅助栈被清空则代表此序列是它的一个弹出序列,否则就不可能是一个弹出序列。

前言

有两个整数序列,第一个序列表示栈的压入顺序,判断第二个序列是否为该栈的弹出顺序。假设压入栈的数字均不相等。例如,序列[1, 2, 3, 4, 5]是某栈的压栈序列,序列[4, 5, 3, 2, 1]是该栈序列对应的一个弹出序列,但[4, 3, 5, 1, 2]就不可能是该压栈序列的弹出序列。

思路分析

仔细分析题目后,我们很直观的想法就是构造一个辅助栈,把压入序列中的数字依次压入该辅助栈。按照弹出序列的顺序依次从该栈中弹出数字,如果辅助栈被清空则代表此序列是它的一个弹出序列,否则就不可能是一个弹出序列。

弹出序列满足条件

如下图所示,它的压入过程为:

取出弹出序列的第1个元素,维护一个已取索引,在压入序列中从已取索引位置开始寻找与之相等的元素,将它之前的数字和其本身依次入栈,每取1个元素就将索引自增1次。

此时,栈顶元素与弹出序列的第1个元素相等,将栈顶元素出栈。

取出弹出序列的第2个元素,在压入序列中从已取索引位置开始寻找与之相等的元素,将它之前的数字和其本身依次入栈。

此时,栈顶元素与弹出序列的第2个元素相等,将栈顶元素出栈。

取出弹出序列的第3个元素,此时,压入序列的元素已经被取完。我们继续判断 辅助栈中的元素是否与弹出序列的元素相等。

栈顶元素为3,要弹出的元素也是3,二者相等,栈顶元素出栈;

取出弹出序列的第4个元素;

栈顶元素为2,要弹出的元素也是2,二者相等,栈顶元素出栈;

取出弹出序列的第5个元素;

栈顶元素为1,要弹出的元素也是1,二者相等,栈顶元素出栈;

弹出序列已取完,辅助栈已清空。 该弹出序列属于压入序列的一个弹出顺序;

弹出序列不满足条件;

接下来,我们来分析下它不是压入序列的弹出顺序的情况,它的压入过程与满足条件时一样,唯独不同的是,弹出序列的第3个元素从辅助栈出栈后,压入序列已经被取完。此时,弹出序列的第4个元素是1,辅助栈的栈顶元素是2,二者不等,那么该序列肯定不是压入序列的弹出顺序。

图片

实现代码

经过上面的分析,我们已经知道了如何解决这个问题。思路已明确,接下来,我们就可以愉快的进入编码环节了。

export function StackPushAndPopSequence(
pushSequence: Array<number>,
popupSequence: Array<number>
): boolean {
if (pushSequence.length === 0 || popupSequence.length === 0) return false;
// 下一个入栈、出栈索引
let nextPushIndex = 0;
let nextPopIndex = 0;
// 辅助栈
const stackData = new Stack();
// 下一个弹出序列存在则执行进一步的判断
while (nextPopIndex < popupSequence.length) {
// 下一个弹出序列的元素与栈顶元素不等则入栈
while (
nextPushIndex < pushSequence.length &&
popupSequence[nextPopIndex] !== stackData.peek()
) {
stackData.push(pushSequence[nextPushIndex]);
nextPushIndex++;
}

// 栈顶元素与下一个弹出序列元素相等则出栈
if (stackData.peek() === popupSequence[nextPopIndex]) {
stackData.pop();
nextPopIndex++;
} else {
// 元素不等则终止循环,此时压入序列已经全部压入辅助栈,该序列不可能是一个弹出序列
break;
}
// 辅助栈清空,则代表弹出序列是正确的
if (stackData.isEmpty()) {
return true;
}
}
return false;
}

最后,我们将开头列举的例子来验证下上述代码是否正确执行,如下所示:

const pushSuite = [1, 2, 3, 4, 5];
const popSuite1 = [4, 5, 3, 2, 1];
const popSuite2 = [4, 3, 5, 1, 2];
const result1 = StackPushAndPopSequence(pushSuite, popSuite1);
const result2 = StackPushAndPopSequence(pushSuite, popSuite2);
console.log(result1, result2);

图片

示例代码

本文所用代码完整版请移步:

  • StackPushAndPopSequence.ts
  • stackPushAndPopSequence-test.ts

责任编辑:武晓燕 来源: 神奇的程序员
相关推荐

2021-12-02 09:13:56

序列压入

2012-05-11 10:22:26

Linuxdirspushd

2022-04-02 09:56:41

Vue2响应式系统

2023-12-28 09:55:08

队列数据结构存储

2012-12-20 09:41:49

JVMJava

2011-06-15 10:53:05

C语言

2023-01-16 08:09:22

PulsarMQ

2022-11-25 18:49:11

云原生

2012-04-13 10:45:59

XML

2022-09-07 07:27:36

函数元素

2022-09-21 23:41:40

机器学习开源数据

2018-11-13 12:52:50

Linux内核栈回溯

2018-03-19 10:20:23

Java序列化反序列化

2010-01-26 17:35:09

C++栈

2013-04-16 10:48:04

Python序列

2010-03-23 10:04:00

JavaScript

2024-02-02 08:25:34

队列与栈Python数据结构

2020-11-26 18:18:21

微服务业务规模技术

2021-07-15 11:31:22

递归匹配参数

2009-06-08 22:01:03

Java堆Java栈区别
点赞
收藏

51CTO技术栈公众号