输入两个整数序列,第一个序列表示栈的压入顺序。请判断第二个序列是否为栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。
这道题的规律如下:如果下一个弹出的数字刚好是栈顶数字,那么直接弹出,如果下一个弹出的数字不在栈顶,我们把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个弹出的数字压入栈顶为止。如果所有的数字都压栈了仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<stack>
using namespace std;
bool IsPopOrder(const int* pPush, const int* pPop, int length)
{
bool possible = false;
if (pPush == NULL || pPop == NULL || length <= 0)
return false;
else
{
const int* curPush = pPush;//压入序列的当前指针
const int* curPop = pPop;//弹出序列的当前指针
stack<int> s;//辅助栈
while (curPop - pPop < length)
{
while (s.empty() || s.top() != *curPop)
{
if (curPush - pPush == length)
break;
s.push(*curPush);
++curPush;
}
//可能是扎钉元素等于弹出序列的元素,也可能是压栈序列全部入栈
if (s.top() != *curPop)
break;
s.pop();
++curPop;
}
if (s.empty() && curPop - pPop == length)
possible = true;
}
return possible;
}
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 5, 4, 3, 2, 1 };
int c[] = { 4, 5, 3, 2, 1 };
int d[] = { 4, 3, 5, 1, 2 };
int sz = sizeof(a) / sizeof(a[0]);
int ret1 = IsPopOrder(a, b, sz);
cout << ret1 << endl;
int ret2 = IsPopOrder(a, c, sz);
cout << ret2 << endl;
int ret3 = IsPopOrder(a, d, sz);
cout << ret3 << endl;
system("pause");
return 0;
}