返回
剑指Offer——栈的压入、弹出序列(JS实现)
前端
2023-10-16 20:35:09
# 标题
# 关键词
#
# 正文
## 前言
作为一名程序员,我们经常会遇到各种各样的数据结构。其中,栈是一种非常重要的数据结构,它遵循后进先出的原则(LIFO),即最后压入的数据会最先弹出。在现实生活中,栈有很多应用场景,例如:
- 浏览器的前进和后退按钮
- 函数调用
- 编译器中的符号表
## 题目
剑指Offer中有一道经典题目“栈的压入、弹出序列”,题目描述如下:
> 给定一个压入栈的序列,判定是否有一个栈能够由这个序列所生成。该栈中只能包含整数,初始情况下为空。每次给出的整数描述一个基本操作,要么把该整数压入栈中,要么把栈顶的整数弹出。
**示例 1:**
```
pushed = [1, 2, 3, 4, 5]
popped = [4, 5, 3, 2, 1]
```
**输出:** true
**解释:** 我们可以模拟栈的操作过程:
```
push(1)
push(2)
push(3)
push(4)
push(5)
pop() // 5
pop() // 4
pop() // 3
pop() // 2
pop() // 1
```
可以看出,压入、弹出序列[1, 2, 3, 4, 5]和[4, 5, 3, 2, 1]是可行的。
**示例 2:**
```
pushed = [1, 2, 3, 4, 5]
popped = [4, 3, 5, 1, 2]
```
**输出:** false
**解释:** 我们可以模拟栈的操作过程:
```
push(1)
push(2)
push(3)
push(4)
push(5)
pop() // 5
pop() // 4
pop() // 3
pop() // 1
pop() // 2
```
可以看出,当我们尝试弹出元素2时,栈中已经为空了。因此,压入、弹出序列[1, 2, 3, 4, 5]和[4, 3, 5, 1, 2]是不可行的。
## 解题思路
本题的思想在于想到模拟栈,我们可以定义一个数组用来模拟栈,从pushed数组的第一个元素开始进行入栈,如果该元素在popped数组中,则进行出栈操作。如果该元素不在popped数组中,则入栈失败,返回false。如果所有元素都入栈成功,则返回true。
## 代码实现
```javascript
/**
* 判断一个压入、弹出序列是否可行
*
* @param {number[]} pushed 压入栈的序列
* @param {number[]} popped 弹出栈的序列
* @return {boolean}
*/
const validateStackSequence = (pushed, popped) => {
const stack = [];
let i = 0;
let j = 0;
while (i < pushed.length) {
stack.push(pushed[i]);
while (stack.length > 0 && stack[stack.length - 1] === popped[j]) {
stack.pop();
j++;
}
i++;
}
return stack.length === 0;
};
```
## 分析
在上面的代码中,我们首先定义了一个名为stack的空数组,用来模拟栈。然后,我们使用两个指针i和j来分别遍历pushed数组和popped数组。
对于pushed数组中的每个元素,我们将其压入栈中。然后,我们检查栈顶元素是否与popped数组中的当前元素相等。如果相等,则说明该元素可以被弹出,因此我们将其弹出栈中并更新指针j。如果栈顶元素与popped数组中的当前元素不相等,则说明该元素无法被弹出,因此我们返回false。
当我们遍历完pushed数组后,如果栈中没有元素了,则说明所有元素都可以被弹出,因此我们返回true。否则,我们返回false。
## 总结
在本文中,我们讨论了剑指Offer中经典题目“栈的压入、弹出序列”的解法。我们使用JavaScript实现了一个模拟栈的算法,并对代码进行了详细的分析。希望这篇博文对您有所帮助!