题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
思路:压入顺序,不满足弹出顺序都有什么?
找规律,假设入栈出栈顺序如下
顺序 pushA
顺序2 5
顺序1 4
顺序0 3
出栈顺序可能有(每push一个元素后,下一步有两个选择,pop当前元素,push下一个元素)
先出3:3 4 5 或 3 5 4
先出4:4 5 3 或 4 3 5
先出5:5 4 3
重点来了,号外号外,为什么先出5的时候,5 3 4不行?
因为栈的结构特性,先出了5说明,之前有3 4 入栈,根据push顺序,3在低 4在顶,所以顺序一定是5 4 3,不能是5 3 4。
结论:我的编码思路是,取pushA栈顶元素,查出在popA中的位置,比较popA位置之前的元素,在pushA中的入栈顺序是否有问题。
这是我的代码,请各位大佬笑纳(代码中还有一些可以优化的地方,比如查找值的位置,其实可以数组hash先存,再查,减少循环次数)
import java.util.ArrayList; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { if((pushA == null || pushA.length == 0) && (popA == null || popA.length == 0)){ return true; } if((pushA == null || pushA.length == 0) || (popA == null || popA.length == 0)){ return false; } for (int i = pushA.length-1; i >= 0; i--) { int stackTop = pushA[i]; int popPoint = 0; // 找pushA栈顶元素,在popA的位置 for (int popNum : popA){ if(popNum == stackTop){ break; } popPoint++; } // 如果pushA栈顶元素在popA中没找到,例如:输入[1] 和 [2]的情况 if(popPoint >= popA.length){ return false; } for (int j = popPoint+2; j < popA.length; j++) { // /* push数组元素 pop数组元素 数组位置4 5 1 数组位置3 4 2 数组位置2 3 3 数组位置1 2 4 数组位置0 1 5 对比5之前元素,是否有非栈顶元素先出的情况 popPoint = 0, 也就是5 j = 2 比较之后两个元素在push的顺序 cur = 3 before = 5 */ int cur = popA[j]; int before = popA[j-1]; if(this.look(before, pushA) < this.look(cur, pushA)){ return false; } } } return true; } // 找一个元素,在数据组中的位置 public int look(int num, int[] array){ for (int i = 0; i < array.length; i++) { if(array[i] == num){ return i; } } return -1; } }