1. 题目描述

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

2. 题目分析

  1. 题目的大致意思是:给你一个栈压入序列A:1 2 3 4 5 ,让你判断第二个序列B是不是该栈的弹出序列
  2. 我们运用一个辅助栈C,将栈A依次压入辅助栈C中,每压一次,判断该压入的元素是不是序列B的首数值。是的话,依次遍历序列B,不是的话,重复压入辅助栈

3. 题目图解

  1. 我们可以看到当1压入栈时,栈C的最上面的元素和弹出序列不同,进行压入操作。
    在这里插入图片描述
  2. 当压入2时,栈C的最上面的元素和弹出序列不同,进行压入操作。
    在这里插入图片描述
  3. 当压入3时,栈C的最上面的元素和弹出序列不同,进行压入操作。

在这里插入图片描述
4. 当压入4时,栈C最上面的元素和弹出序列相同,我们把4出栈,并且比较弹出序列的下一个元素。
在这里插入图片描述
5. 继续比较栈C的最上面的元素和弹出序列是否一样。我们可以看到此时不一样,所以,继续进行入栈操作。
在这里插入图片描述

  1. 比较栈C的最上面的元素和弹出序列是否一样。一样的话栈C进行出栈操作,弹出序列指针下移。
    在这里插入图片描述

  2. 重复以上操作,最后判断辅助栈C里面是否为空,来判断是不是原序列的弹出序列。

4. 题目代码

public class Test19 {

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

    public static void main(String[] args) {
        int[] a = new int[] { 1, 2, 3, 4, 5 };
        int[] b = new int[] { 4, 5, 3, 2, 1 };
        boolean flag = false;
        flag = IsPopOrder(a, b);
        System.out.println(flag);
    }

    public static boolean IsPopOrder(int[] pushA, int[] popA) {
        if (pushA.length == 0 || popA.length == 0) {
            return false;
        }
        Stack<Integer> stack = new Stack<>();
        int num = 0;
        for (int i = 0; i < pushA.length; i++) {
            stack.add(pushA[i]);
            while (!stack.empty() && stack.peek() == popA[num]) {
                stack.pop();
                num++;
            }
        }
        return stack.empty();
    }
}