剑指Offer(二十一)——栈的压入、弹出序列

题目描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
 

题目分析:

判断出栈顺序是否为入栈顺序的一种出栈情况,我们可以用一个栈去模拟进出情况。

模拟方法:
根据入栈顺序和出栈顺序的第一个元素确定,第一次何时出栈。第一次出栈后栈中都省了哪些元素。
在继续入栈,根据出栈舒顺序的第二个元素确定,第二次合适出栈,第二次出栈后都剩了什么。
……
知道所有的元素都入栈完毕,此时是第j次出栈完,因为不会再入栈了,所以栈剩下所有元素依次出栈的顺序就是   出栈数组j之后的顺序。
 
链接:https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106?answerType=1&f=discussion
来源:牛客网
举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶1≠4,继续入栈2
此时栈顶2≠4,继续入栈3
此时栈顶3≠4,继续入栈4
此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3
此时栈顶3≠5,继续入栈5
此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3
 
用图解释一下:
 
                123直接入栈,4入了又出,不必入栈。

 

 

5也是入了又出,此时入栈顺序遍历完,栈中剩下321,正好对应出栈顺序5之后的元素

 

 

 1 伪代码:
 2 
 3 int j=0;
 4 
 5 for(int i=0;i<入栈顺序大小;i++) {
 6 
 7   if(入栈元素i==出栈元素j) {
 8 
 9     入了又出,不用加到模拟栈中;
10 
11     j++;//再出就是下一个了
12 
13   }
14 
15   else {
16 
17     入栈元素不是出栈元素,说明被压住了,存到模拟栈中;
18 
19   }
20 
21 }
22 
23 此时入栈顺序遍历完,j是下一个要出的元素,之后的顺序要和模拟栈中元素一致。
24 
25 for(;j<出栈顺序大小;j++) {
26 
27   if(出栈元素j  不等于 栈顶 ){
28 
29     有错误return false;
30 
31   }
32 
33   若相等,就模拟栈出栈,判断下一个
34 
35 }
36 
37 //出栈遍历完,没有问题
38 
39 return true;

 

 附上本人代码和运行结果:

#include<stack>
class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        int j=0;
        for(int i = 0;i<pushV.size();i++) {
            if(pushV[i] == popV[j]) {
                j++;                
            }
            else {
                sck.push(pushV[i]);
            }
        }
        //入栈顺序完
        for(;j<popV.size();j++) {
            if(popV[j] != sck.top()) {
                return false;
            }
            sck.pop();
        }
        return true;
    }
private:
    stack<int> sck;
};

 

 

 


 

 解决方法性能分析:两个单独的for时间复杂度n+n,o(n);空间上用了辅助栈o(n)。

对于代码的简洁性,简单优化了一下,运行时间由5ms变成4ms。

#include<stack>
class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        int j=0;
        for(int i = 0;i<pushV.size();i++) {
            if(pushV[i] == popV[j]) 
                j++; 
            else
            sck.push(pushV[i]);
        }
        //入栈顺序完
        for(;j<popV.size() && popV[j] == sck.top();j++)
              sck.pop();
        return sck.empty();
    }
private:
    stack<int> sck;
    
};

 

如有疏漏,欢迎指正。

 

posted @ 2019-10-27 17:00  碎梦残阳  阅读(61)  评论(0)    收藏  举报