剑指 Offer 31. 栈的压入、弹出序列

题目描述

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

示例 1:

1
2
3
4
5
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

1
2
3
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

提示:

  1. $0 <= pushed.length == popped.length <= 1000$
  2. $0 <= pushed[i], popped[i] < 1000$
  3. $pushed$ 是 $popped$ 的排列。

注意:本题与主站 946 题相同:https://leetcode-cn.com/problems/validate-stack-sequences/


算法

(栈,模拟) $O(n)$

使用两个序列来模拟压栈和出栈的过程,如果整个过程没有矛盾,则是一个合法的出栈序列。

算法步骤:

  1. 首先定义一个栈 $stk$ 和一个指针 $i$ 用来指向出栈序列,开始模拟。
  2. 遍历压栈序列,对于每个数直接压入栈中
  3. 此时如果栈不为空且栈顶等于出栈序列中的 $poped[i]$,则把当前数弹栈,同时 $i$ 指针往后移,循环此过程。

最后如果栈为空则说明整个压入弹出过程没有矛盾,返回 $true$,否则返回 $false$。

时间复杂度

每个数最多只会入栈出栈一次,所以时间复杂度为 $O(n)$。

空间复杂度

$O(n)$

C++ 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> stk;
int i = 0;
for (auto x : pushed) {
stk.push(x);
while (stk.size() && stk.top() == popped[i]) {
stk.pop();
i ++ ;
}
}
return stk.empty();
}
};
Author: tonngw
Link: https://tonngw.com/2022/07/08/剑指 Offer/剑指 Offer 31. 栈的压入、弹出序列/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.