题目描述:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
测试用例:
1)功能测试(输入的两个数组含有多个数字或者只有一个数字;是或者不是压入序列对应的栈的弹出序列)
2)特殊输入测试(输入两个nullptr指针)
解题思路:
1)使用辅助栈:
如果下一个弹出的数字刚好是栈顶数字,那么直接弹出;如果下一个弹出的数字不在栈顶,则把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止;如果所有数字都压入栈后仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
//特殊输入处理
if(pushV.size()!=popV.size() || pushV.empty() || popV.empty())
return false;
//使用辅助栈存储入栈的数字
stack <int> stackData;
int length = pushV.size();
int pushIndex = 0;
int popIndex = 0;
//遍历每个要删除的元素
while(popIndex<length){
//入栈,直到栈顶元素等于当前要删除的元素,删除栈顶元素
while(stackData.empty() || stackData.top()!= popV[popIndex]){
//没有入栈元素,或者所有元素都已经入栈,终止
//if(pushIndex>length-1)
if(pushIndex==length) //若直到所有元素都已经入栈,栈顶元素还不等于要删除的元素,说明弹出序列不符
return false;
stackData.push(pushV[pushIndex]);
pushIndex++;
}
//若直到所有元素都已经入栈,栈顶元素还不等于要删除的元素,说明弹出序列不符
//if(stackData.top()!=popV[popIndex])
//return false;
//弹出当前元素
stackData.pop();
//判断下一个弹出序列
popIndex++;
}
return true;
}
};
2)使用辅助栈:每一压入一个元素,判断栈顶元素是否需要删除(while循环,因为可能同时删除多个元素)
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
if(pushV.size() == 0) return false;
vector<int> stack;
for(int i = 0,j = 0 ;i < pushV.size();){
stack.push_back(pushV[i++]); //每次压入一个元素
while(j < popV.size() && stack.back() == popV[j]){ //
stack.pop_back();
j++;
}
}
return stack.empty();
}
};
3)不一样的思路:(python)
1.先取出pop序列的第一个(比如pop【3,2,4,5,1】),在push序列中找到这个位置,push【1,2,3,4,5】,
2.此时找到了3的位置.那么下一个pop的数字(此时的数字是2)必然是,push中3的前一个数字,或者后面的数字(后面可以不相邻的数字)。否则返回False
如此循环直到最后,判断长度相等,就是弹出序列。否则返回False.
# -*- coding:utf-8-*-
classSolution:
def IsPopOrder(self, pushV, popV):
# write code here
iflen(pushV) != len(popV):
returnFalse
elif len(pushV) ==0:
returnFalse
x = popV[0]
ifx not in pushV:
returnFalse
fori in range(len(popV)):
position = pushV.index(popV[i])
iflen(pushV) ==1:
ifpushV[0] == popV[i]:
returnTrue
try:
ifpopV[i+1] == pushV[position-1]:
pushV.remove(pushV[position])
elif popV[i+1] in pushV[position:]:
pushV.remove(pushV[position])
else:
returnFalse
except IndexError:
returnFalse
else:
returnTrue
4)不使用辅助空间
//不使用辅助空间
class Solution {
public:
bool IsPopOrder(vector<int> pushV, vector<int> popV){
int canBePoped1,canBePoped2; // 创建两个可能出栈的下一位数变量
int m = pushV.size(); int n = popV.size();
if(m == 0 || n == 0 || m < n) return false;
auto iter = find(pushV.begin(),pushV.end(),popV[0]);
if(iter == pushV.end()) return false;
// 在pushV中找到数的位置的三种情况
if(iter == pushV.begin()) {
canBePoped1 = *(iter + 1);
canBePoped2 = *(iter + 1);
}
else if(iter == pushV.end()-1){
canBePoped1 = *(iter-1);
canBePoped2 = *(iter-1);
}
else{
canBePoped1 = *(iter-1);
canBePoped2 = *(iter+1);
}
pushV.erase(iter); // 删掉已找到过的数
for(auto iter1 = popV.begin()+1; iter1!= popV.end(); ++iter1){
if(*iter1 != canBePoped1 && *iter != canBePoped2) return false; // 遍历popV的数若不等于任何一个可能的下一位
auto iter2 = find(pushV.begin(),pushV.end(),*iter1); // 在pushV中找到数后更新下两个可能的数
if(iter2 == pushV.end()) return false;
if(iter2 == pushV.begin()){
canBePoped1 = *(iter2+1);
canBePoped2 = *(iter2+1);
}
else if(iter2 == pushV.end()-1){
canBePoped1 = *(iter2-1);
canBePoped2 = *(iter2-1);
}
else{
canBePoped1 = *(iter2-1);
canBePoped2 = *(iter2+1);
}
pushV.erase(iter2);
}
return true;
}
};