JZ31. 栈的压入弹出序列

Posted 2021dragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZ31. 栈的压入弹出序列相关的知识,希望对你有一定的参考价值。

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

提示: 这两个序列的长度是相等的。

示例:
 输入:pushed = [1, 2, 3, 4, 5],poped = [4, 5, 3, 2, 1]
 输出:true

思路:
对于该题目,我们可以使用一个栈来模拟进行第一个序列的入栈和出栈操作,如果可以模拟出第二个序列,则第二个序列是以第一个序列为压栈顺序的某一弹出序列。

首先用两个变量 i 和 j ,分别索引当前正在遍历的两个序列的元素位置。然后开始循环执行以下过程,直到第一个序列被遍历完毕为止:

  1. 先将第一个序列当中 i 索引的元素压栈,然后 i 转而索引第一个序列的后一个元素。
  2. 判断栈顶元素与第二个序列当中 j 索引的元素是否相同,若相同则将栈顶的元素弹出,然后 j 转而索引第二个序列的后一个元素,并继续当前判断,直到栈顶元素与 j 索引的元素不同或是栈已经为空为止。

当该过程执行完毕后,若第二个序列已经遍历完毕或者说栈已经为空(选一个作为最终判断即可),则第二个序列是以第一个序列为压栈顺序的某一弹出序列。

下面我们以就以上面给出的示例为列,具体说明一下:
首先,初始状态下,让 i 和 j 分别指向第一个序列和第二个序列的第一个元素。

然后让 i 索引的元素入栈,并让 i 转而索引后一个元素。

接着判断栈顶元素与 j 索引的元素是否相同,此时不同,则继续将 i 索引的元素入栈,并让 i 转而索引后一个元素。

然后再判断栈顶元素与 j 索引的元素是否相同,此时还是不同,则继续将 i 索引的元素入栈,并让 i 转而索引后一个元素。

紧接着再判断栈顶元素与 j 索引的元素是否相同,此时还是不同,则继续将 i 索引的元素入栈,并让 i 转而索引后一个元素。

这时我们发现栈顶元素与 j 索引的元素相同,则将栈顶的元素弹出,并让 j 转而索引后一个元素。

然后我们又判断栈顶元素与 j 索引的元素是否相同,此时不同,则继续将 i 索引的元素入栈,并让 i 转而索引后一个元素。

这时我们再次发现栈顶元素与 j 索引的元素相同,则将栈顶的元素弹出,并让 j 转而索引后一个元素。

此时发现栈顶元素与 j 索引的元素还是相同的,则将栈顶的元素继续弹出,并让 j 转而索引后一个元素。

栈顶元素与 j 索引的元素还是相同的,则将栈顶的元素继续弹出,并让 j 转而索引后一个元素。

栈顶元素与 j 索引的元素还是相同的,则将栈顶的元素继续弹出,并让 j 转而索引后一个元素。

好了现在栈空了,不能再判断栈顶的元素与 j 索引的元素是否相同了,现在本该继续将 i 索引的元素入栈,但现在 i 已经指向第一个序列末尾,于是操作结束。现在我们发现第二个序列也已经遍历完毕或者说栈现在已经为空,于是得出结论:第二个序列{4, 5, 3, 2, 1}是以第一个序列{1, 2, 3, 4, 5}为压栈顺序的某一弹出序列。

代码如下:

class Solution {
public:
	bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
		size_t i = 0, j = 0; //分别索引当前正在遍历的两个序列的元素位置
		stack<int> st; //辅助栈
		while (i < pushed.size()) //反复执行该操作,直到第一个序列被遍历完毕
		{
			st.push(pushed[i]); //将第一个序列当中i索引的元素压栈
			while (!st.empty() && st.top() == popped[j]) //判断栈顶元素与第二个序列当中j索引的元素是否相同,直到栈顶元素与j索引的元素不同或是栈已经为空为止
			{
				st.pop(); //若相同则将栈顶的元素弹出
				j++; //j转而索引第二个序列的后一个元素,并继续当前判断
			}
			i++; //索引pushed容器中的下一个元素
		}
		//return j == popped.size(); //判断第二个序列是否遍历完毕,若是,则匹配
		return st.empty(); //判断辅助栈是否为空,为空则匹配
	}
};

以上是关于JZ31. 栈的压入弹出序列的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer(C++)-JZ31:栈的压入弹出序列(数据结构-队列 & 栈)

剑指offer(C++)-JZ31:栈的压入弹出序列(数据结构-队列 & 栈)

剑指offer(C++)-JZ31:栈的压入弹出序列(数据结构-队列 & 栈)

Offer[31] 栈的压入弹出序列

剑指offer--31栈的压入弹出序列

剑指offer--31栈的压入弹出序列