给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作
题目描述
给定两个序列 pushed
和 popped
,每个序列中的值都不重复。我们需要判断,是否可以通过一系列栈的推入(push)和弹出(pop)操作,将 pushed
序列变成 popped
序列。换句话说,验证这两个序列是否可能是在最初为空的栈上进行的一系列栈操作的结果。
题目分析
-
栈的基本操作:栈是一种先进后出(LIFO)的数据结构,它只允许在栈顶进行插入(push)和删除(pop)操作。
-
任务目标:给定两个序列
pushed
和popped
,验证它们是否可能是栈操作的合法推入与弹出顺序。- 推入序列
pushed
:表示按顺序推入栈的元素。 - 弹出序列
popped
:表示按顺序弹出的元素。
我们需要判断,在最初为空的栈上,是否能够按照
pushed
顺序推入栈,并按照popped
顺序弹出栈。 - 推入序列
解决思路
栈操作的核心思想是 "先进后出"。因此,要验证 popped
序列是否能够在 pushed
序列的推动下产生,可以模拟栈的操作:
- 遍历
pushed
序列,将每个元素压入栈中。 - 每当栈顶元素与
popped
当前元素相等时,将栈顶元素弹出,并继续验证popped
中的下一个元素。 - 如果在整个过程中,所有的弹出操作都可以顺利进行,且最终
popped
中所有元素都被弹出,则返回true
。 - 否则,返回
false
。class Solution { public: bool validateStackSequences(vector<int>& pushed, vector<int>& popped) { stack<int> stp; int j=0; for(auto e: pushed){ stp.push(e); while(!stp.empty()&&stp.top()==popped[j]){ j++; stp.pop(); } } return j==pushed.size(); } };
代码解释
- 栈模拟:我们使用一个栈
stp
来模拟栈的操作。遍历pushed
数组,将每个元素压入栈。 - 弹出条件判断:在每次压入栈后,我们检查栈顶元素是否与
popped
数组中的当前元素相等。如果相等,弹出栈顶元素,并将指针j
移动到下一个元素。重复这个过程,直到栈顶元素与当前的popped[j]
不相等或者栈为空。 - 最终判断:如果最终指针
j
已经遍历完popped
数组,则说明所有的弹出操作都成功完成,返回true
。否则返回false
。 - 时间复杂度:
O(n)
,其中n
是pushed
数组的长度。每个元素至多入栈一次并出栈一次,因此时间复杂度是线性的。 - 空间复杂度:
O(n)
,我们使用了一个栈来存储最多n
个元素,因此空间复杂度是O(n)
。 - 本问题通过模拟栈的推入和弹出操作来验证是否能从
pushed
序列生成popped
序列。核心思想是利用栈的先进后出(LIFO)特性,通过遍历和栈操作逐步模拟弹出操作。 - 使用栈的本质特性,结合指针遍历
popped
数组来完成验证过程,确保解法高效且易于理解。