29.栈的push、pop 序列
题目:输入两个整数序列。其中一个序列表示栈的push 顺序,
判断另一个序列有没有可能是对应的pop 顺序。
为了简单起见,我们假设push 序列的任意两个整数都是不相等的。
比如输入的push 序列是1、2、3、4、5,那么4、5、3、2、1 就有可能是一个pop 系列。
因为可以有如下的push 和pop 序列:
push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,
这样得到的pop 序列就是4、5、3、2、1。
但序列4、3、5、1、2 就不可能是push 序列1、2、3、4、5 的pop 序列。
思路: 我们可以实际的推演一下入栈出栈过程,
先从第0个元素开始依次查看pop序列中的元素data,
栈顶元素和data的关系有:
1、没有栈顶元素,栈为空,那么在push序列中查找data元素,并把data元素及其前面没有入栈的元素入栈
2、栈顶元素等于data,那么栈顶元素出栈,查看pop序列中下一个元素
3、栈元素不等于data,如果data已经入栈,说明该pop序列没有办法得到,如果data还没有入栈,
按照1中的方法,将该元素及其前面没有入栈的元素入栈
最终,pop序列遍历完成后,栈应该也为空了。
代码:
/*
思路: 我们可以实际的推演一下入栈出栈过程,
先从第0个元素开始依次查看pop序列中的元素data,
栈顶元素和data的关系有:
1、没有栈顶元素,栈为空,那么在push序列中查找data元素,并把data元素及其前面没有入栈的元素入栈
2、栈顶元素等于data,那么栈顶元素出栈,查看pop序列中下一个元素
3、栈元素不等于data,如果data已经入栈,说明该pop序列没有办法得到,如果data还没有入栈,
按照1中的方法,将该元素及其前面没有入栈的元素入栈
最终,pop序列遍历完成后,栈应该也为空了。
*/
#include <vector>
#include <stack>
#include <cassert>
#include <iostream>
using namespace std;
template <typename T>
class CheckSequenceHelper
{
public:
CheckSequenceHelper(vector<T> &elements):m_elements(elements)
{
}
bool isPossiblePopStackSequence(vector<T> &popSequence)
{
stack<int> indexStack;
int lastPushedIndex = -1;
for (int i = 0; i < popSequence.size(); i++)
{
int popIndex = indexOfElement(popSequence[i]);
assert(popIndex != -1);
if (popIndex == -1)
{
return false;
}
// this means we have push this element into stack,
// but it's not on the top right now,can't pop
if ((indexStack.size() != 0) && (popIndex < indexStack.top()))
{
return false;
}
if ((indexStack.size() == 0) || (indexStack.top() != popIndex))
{
for (int index = lastPushedIndex + 1; index <= popIndex; index++)
{
indexStack.push(index);
}
lastPushedIndex = popIndex;
}
assert(popIndex == indexStack.top());
indexStack.pop();
}
assert(indexStack.size() == 0);
return true;
}
int indexOfElement(T element)
{
for (int i = 0; i < m_elements.size(); i++)
{
if (m_elements[i] == element)
return i;
}
return -1;
}
private:
vector<T> m_elements;
};
int main(void)
{
vector<int> pushed;
vector<int> poped;
pushed.push_back(1);
pushed.push_back(2);
pushed.push_back(3);
pushed.push_back(4);
pushed.push_back(5);
poped.push_back(5);
poped.push_back(4);
poped.push_back(1);
poped.push_back(2);
poped.push_back(3);
CheckSequenceHelper<int> helper(pushed);
bool flag = helper.isPossiblePopStackSequence(poped);
if (flag)
cout << "YES!!!" << endl;
else
cout << "NO" << endl;
system("pause");
return 0;
}