题目
给定两个序列,判断第二个序列是否是第一个序列顺序压入时的弹出序列
考察点
- 栈 :栈规定的先入先出是指压入弹出的位置,而非元素压入弹出的时间
解题思路
添加一个辅助栈,顺序压入第一个序列元素,当栈顶元素与弹出序列的元素相同时,直接弹出,否知,一直压入,直至找到相同元素,若所元素压入完还为找到,即表示弹出序列不是压入序列的一种弹出方式。
完整代码
/*21-栈的压入、弹出序列*/
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
class Solution {
public:
bool IsPopOrder(vector<int> pushV, vector<int> popV)
{
int length = popV.size();
if (length != pushV.size()) return false;
//构建一个辅助栈,对比着popV顺序压入pushV
stack<int> spush;
int j = 0;
for (int i = 0; i < length; i++)
{
spush.push(pushV[i]);
while (!spush.empty() && spush.top() == popV[j])
{
spush.pop();
j++;
}
}
return spush.empty();
}
};
int main()
{
vector<int> pushV = { 1,2,3,4,5 };
vector<int> popV1 = { 4,5,3,2,1 };
vector<int> popV2 = { 4,3,5,1,2 };
Solution s;
cout << s.IsPopOrder(pushV, popV1) << endl;
cout << s.IsPopOrder(pushV, popV2) << endl;
return 0;
}
编程问题
- 一开始我设定两个栈来分别装两个序列元素。并将popV倒序装入spop方便后面比较:
stack<int> spop;//倒序放置要判断的序列,方便后面弹出操作(即相同时下移)
for (int i = length - 1; i >= 0; i--)
{
spop.push(popV[i]);
}
for (int i = 0; i < length; i++)
{
spush.push(pushV[i]);
while (!spush.empty() && spush.top() == spop.top())
{
spush.pop();
spop.pop();
}
}
但后来参考了别人的代码,发现不用重新定义一个栈,直接在popV数组上进行后移操作即可。
int j = 0;
for (int i = 0; i < length; i++)
{
spush.push(pushV[i]);
while (!spush.empty() && spush.top() == popV[j])
{
spush.pop();
j++;
}
}
- 循环的问题:
刚开始在判断元素是否相同时,我在大循环中使用了if语句来判断,这就造成了当按照数组长度来循环的时候,i走完了,元素压入弹出操作还没结束。后改用while进行循环操作。