1. 题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
2. 题目分析
- 题目的大致意思是:给你一个栈压入序列A:1 2 3 4 5 ,让你判断第二个序列B是不是该栈的弹出序列
- 我们运用一个辅助栈C,将栈A依次压入辅助栈C中,每压一次,判断该压入的元素是不是序列B的首数值。是的话,依次遍历序列B,不是的话,重复压入辅助栈
3. 题目图解
- 我们可以看到当1压入栈时,栈C的最上面的元素和弹出序列不同,进行压入操作。
- 当压入2时,栈C的最上面的元素和弹出序列不同,进行压入操作。
- 当压入3时,栈C的最上面的元素和弹出序列不同,进行压入操作。
4. 当压入4时,栈C最上面的元素和弹出序列相同,我们把4出栈,并且比较弹出序列的下一个元素。
5. 继续比较栈C的最上面的元素和弹出序列是否一样。我们可以看到此时不一样,所以,继续进行入栈操作。
- 比较栈C的最上面的元素和弹出序列是否一样。一样的话栈C进行出栈操作,弹出序列指针下移。
- 重复以上操作,最后判断辅助栈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();
}
}