面试题31:栈的压入、弹出序列。输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。
解决这个问题很直观的想法是建立一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从栈中弹出数字。
判断方法:如果下一个要弹出的数字刚好等于栈顶数字,那么直接弹出。如果下一个要弹出的数字不等于栈顶数字,那么把压栈序列的数字继续压入辅助栈,直到把要弹出的数字压入栈顶为止。如果所有数字都压入栈后仍然没有找到下一个要弹出的数字,那么该序列不是一个弹出序列:
#include <iostream>
#include <stack>
using namespace std;
bool IsPopOrder(const int* pPush, const int *pPop, const int length) {
if (pPush == nullptr || pPop == nullptr || length < 1) {
return false;
}
stack<int> dataStack;
const int* pNextPush = pPush, * pNextPop = pPop;
while (pNextPop - pPop < length) { //弹出序列还没弹完时
while (dataStack.empty() || dataStack.top() != *pNextPop) { //此时栈为空或栈顶元素和要弹出的元素值不同,则继续压栈
if (pNextPush - pPush == length) { //压栈序列结束
break;
}
dataStack.push(*pNextPush);
++pNextPush;
}
if (dataStack.top() != *pNextPop) { //上述循环结束时,要么栈顶元素与要弹出的值相等,要么不相等并且压入序列结束,当后一种情况时
break;
}
dataStack.pop();
++pNextPop;
}
if (dataStack.empty() && pNextPop - pPop == length) { //当栈为空且弹出序列结束时,匹配成功
return true;
}
return false;
}
int main() {
int push[] = { 1 };
int pop[] = { 1,0 };
if (IsPopOrder(push, pop, 1)) {
cout << "匹配成功。" << endl;
}
else {
cout << "匹配失败。" << endl;
}
}
以上为剑指offer中的代码,但该代码没有对push和pop序列长度做出判断,造成以上的输入也能匹配成功。因此最好再加上判断压入弹出序列长度是否相等且等于length的代码。