题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
原题链接:牛客网
问题分析
这个问题从模拟栈的元素的出栈会很好理解——假设给定入栈序列in,出栈序列out。然后需要先知道一个事实——出栈的元素可以分为两种:(1)当前的栈顶元素(进栈后又马上出栈了);(2)曾经的栈顶元素(入栈后没有马上出栈)。
而(1)是最关键的突破点,因为它先出栈了,它在out序列中的位置必定比其它还没出栈的元素的前面。
那么只管按in的顺序入栈,直到栈顶元素和出栈序列的首个元素相同为止,此时表示该元素必定是出栈了(因为它在其它所有元素的前面嘛,上面分析过的),pop掉,并且out序列的首部元素往后挪一个位置。这时在继续将in序列后续的元素入栈之前,先检查一下栈里的元素是否是后续出栈的元素,如果是的话,就将相应的元素出栈;否则就继续将in序列后续的元素入栈。
// 后续有空再画张图,其实代码也很容易看懂这个过程~
class Solution {
public:
bool IsPopOrder(vector<int> pushV, vector<int> popV) {
if (pushV.size() != popV.size())
return false;
// 题目的测试案例要求两个都为空时输出false,不明觉厉
if (pushV.empty())
return false;
int len = pushV.size(), push = 0, pop = 0;
stack<int> s;
while (push < len && pop < len) {
if (pushV[push] != popV[pop]) {
s.push(pushV[push]);
++push;
continue;
}
++push;
while (!s.empty() && ++pop < len && s.top() == popV[pop])
s.pop();
}
return s.empty();
}
};