9 栈的弹出序列正确性判断

0 引言

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

1 抽象问题具体化

 举例1:序列1,2,3,4,5为某栈的压入顺序,判断4,5,3,2,1是否为该压栈序列对应的一个弹出序列。

可知4,5,3,2,1是该压栈序列对应的一个弹出序列

举例2:序列1,2,3,4,5为某栈的压入顺序,判断4,3,5,1,2是否为该压栈序列对应的一个弹出序列。

 

可知4,3,5,1,2不是该压栈序列对应的一个弹出序列。

2 具体问题抽象分析

 根据压栈顺序以及出栈序列,对当前栈状态进行判断分析。

1)遍历出栈序列,访问数num;

2)根据num对辅助栈进行操作,将num之前的数入栈myStack,之后的数入队myQueue.

3)逐个遍历出栈序列中的数,分三种情况进行处理。

  1. 当前数据在栈顶,继续访问出栈序列;

  2. 当前数据不在栈顶,到队列中去找,没有找到,直接返回false;

  3. 当前数据不在栈顶,到队列中去找,找到了,将该数在队列中的位置返回,并将该数之前的数出对入栈,将该数本身出队不入栈。

4)遍历完毕,表示所有的出战序列中的数均判读完毕合格,最后返回true.

3 demo 

    int FindNumInQueue(int num, queue<int> myQueue){
        int position = -1;
        bool myBool = false;
        while(!myQueue.empty()){
            if(myQueue.front() == num){
                ++ position;
                myBool = true;
                break;
            }            
            myQueue.pop();
            ++ position;
        }
        if(myBool)
            return position;
        else
            return -1;
    }
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        if(pushV.empty() || popV.empty())
            return true;
        stack<int> myStack;   // 入栈了的数
        queue<int> myQueue;   // 未入栈的数
        int seprateIndex = -1;
        for(int i = 0; i<pushV.size();i++){
            if(pushV[i] == popV[0])
                seprateIndex = i;
        }
        for(int i = 0; i <= seprateIndex;i++)
            myStack.push(pushV[i]);
        for(int i = seprateIndex + 1; i < pushV.size();i++)
            myQueue.push(pushV[i]);            
        // 遍历出栈序列,逐个判断
        for(int i=0;i<popV.size();i++){
            // 第一种情况:当前数据在栈顶,继续
            bool myBool = false;
            if(!myStack.empty()){
                if(popV[i] == myStack.top())
                    myStack.pop();
                else 
                    myBool = true;
            }
            else
                myBool = true;
            if(myBool){
                // 第二种情况:不在栈顶,去队列里边找,找不到,返回false
                int position = FindNumInQueue(popV[i],myQueue); 
                if(position == -1)
                    return false;
                // 第三种情况:不在栈顶,去队列里边找,找到了,将前边的出队并入栈
                else{
                    for(int i = 0 ;i< position;i++){
                        myStack.push(myQueue.front());
                        myQueue.pop();
                    }
                    myQueue.pop();
                }
            }            
        }
        return true;
    }

4 代码优化

 代码逻辑存在冗余的地方,后边慢慢修改吧,一时之间没有什么思路。

原文地址:https://www.cnblogs.com/ghjnwk/p/10024554.html