剑指offer系列——21.栈的压入、弹出系列

Q:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
T:
1.(感谢@kiss90)
模拟堆栈操作:将原数列依次压栈,栈顶元素与所给出栈队列相比,如果相同则出栈,
如果不同则继续压栈,直到原数列中所有数字压栈完毕。
检测栈中是否为空,若空,说明出栈队列可由原数列进行栈操作得到。否则,说明出栈队列不能由原数列进行栈操作得到。

    bool IsPopOrder(vector<int> pushV, vector<int> popV) {
        if (pushV.empty() && popV.empty())
            return true;
        stack<int> s;
        int out = 0;
        for (int i = 0; i < pushV.size(); i++) {
            s.push(pushV[i]);
            while (!s.empty() && s.top() == popV[out]) {
                s.pop();
                out++;
            }
        }
        return s.empty();
    }

2.(感谢@flyliu)
有个递归思路来解,假设pushA中的元素为Xi,popA被X0分割成两个序列p1和p2,因为X0是第一个入栈的元素,所以p1中的元素必定比p2中的元素先入栈,则这两个序列必然都满足弹出序列。
设p1长度为m,则p1对应的入栈序列为X[1:m+1],p2对应X[m+1:n],n是原来序列的长度。

import java.util.Arrays;
  
 public class PopOrder {
   
  public boolean IsPopOrder(int [] pushA,int [] popA) {
   int length=popA.length;
   if(length==0)
       return true;
   if(length==1)
       return popA[0]==pushA[0];
   int i;
   for (i = 0; i < popA.length; i++) {
       if(popA[i]==pushA[0])
           break;
   }
   return IsPopOrder(Arrays.copyOfRange(pushA, 1, i+1),Arrays.copyOfRange(popA, 0, i)) && IsPopOrder(Arrays.copyOfRange(pushA, i+1, length),Arrays.copyOfRange(popA, i+1,length));
 }

P.S.我的思路:取出弹出序列的第一个元素,然后找到此元素在入栈序列的位置n,那么入栈序列的前n个元素如果依次等于弹出序列从后往前数的n个元素,那么此弹出序列就是正确的弹出序列。我最后写的失败了,在讨论区 @收获2018 成功了,但从回复内容而言,也是不完全正确的。

原文地址:https://www.cnblogs.com/xym4869/p/12274627.html