题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)。
解题思路
题目中的所有数据都不相同是题眼,根据这个,可以模拟压栈,然后根据弹出顺序,每一次压入之后,和弹出序列中相比,然后将相等的值弹出,同时移动指向弹出序列的指针,当压栈序列所有元素都已经遍历过一遍,如果栈中没有元素了,返回true,否则返回false。
另一种思路是从弹出序列看,比如按照入栈序列入栈之后弹出的序列是5,4,3,2,1,但是如果现在考察的序列是3,5,4,2,1那么说明在入栈到3的时候弹出,然后继续入栈,到5弹出,所以说当后面弹出的值大于当前的值是没有问题的,但是如果小于这个值,那么就必须保证这两个之间所有数全部弹出,比如在4之后弹出的2,4和2之间有个3,弹出之后就可以在4之后弹出2。这种思路需要先将入栈序列做一个映射,将序列中的数映射到1-n,然后映射相应的弹出序列。
代码实现
思路一:
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
stack<int> data;
int len=pushV.size();
if(len==0) return false;
int i=0,j=0;
for(i=0;i<len;i++){
data.push(pushV[i]);
while(!data.empty()&&data.top()==popV[j]){
data.pop();
j++;
}
}
if(data.size())
return false;
return true;
}
};
思路二:
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
int n=pushV.size(),i;
vector<int> visit(n+1,0);
map<int,int> mapper;
for(i=n;i>=1;i--)
mapper[pushV[i-1]]=i;
for(i=0;i<n;i++){
if(mapper.count(popV[i])==0)
return false;
popV[i]=mapper[popV[i]];
}
int last=popV[0],tmp,j;
visit[last]=1;
for(i=1;i<n;i++){
tmp=popV[i];
if(visit[tmp]) return false;
visit[tmp]=1;
if(tmp<last){
j=last-1;
while(j>tmp&&visit[j])
j--;
if(j!=tmp)
return false;
}
last=tmp;
}
return true;
}
};