牛客算法AB2 栈的压入、弹出序列 详细注释

53 阅读2分钟

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

解法一:借用辅助栈

public static boolean IsPopOrder (int[] pushV, int[] popV) {
    // write code here
    Stack<Integer> stack = new Stack<>();  //创建一个辅助栈

    int i = 0; //i用来遍历入栈的下标
    //j用来遍历出栈的下标
    for(int j = 0;  j< pushV.length; j++){
        //入栈的条件,i的下标比长度小,且栈为空或者栈顶元素和待匹配元素不同
        //主要为了避免这种特殊情况 [1]  [2]
        while( i < pushV.length && (stack.isEmpty()||stack.peek()!=popV[j]) ){
            stack.push(pushV[i]); //插入元素
            i++; //移动遍历入栈的下标
        }
        //当执行到该if语句的时候只有可能两种情况 1. pushV被遍历完了,或者是栈顶元素和目前的出栈元素相同
        //如果pushV被遍历完了但是栈顶元素和目前的待出栈元素不同直接返回false;
        if(stack.peek() == popV[j]){
            stack.pop();
        }else
            return false;
    }
    return true;

解法二:原地栈

将push数组模拟成栈,来进行入栈和出栈操作,但是整个过程会对原始数组进行修改。

    public static boolean IsPopOrder (int[] pushV, int[] popV) {
        // 将pushV数组视为一个栈,利用数组前边使用过的部分

        int n = 0; // 表示目前栈空间的大小
        int j = 0; // 出栈序列的下标
        for (int number : pushV) { //遍历待插入数组
            //将该元素插入数组,需要注意的是在后续的操作中可能会出现元素覆盖,主要是因为有的元素逻辑上已经出栈,这部分存储就不需要了
            pushV[n] = number;
            //当栈顶元素与序列元素比较,相同进行出栈操作,此时出栈元素所处的空间就可以被覆盖
            while(n >= 0 && pushV[n] ==popV[j]){
                j++;
                n--;
            }
            n++; //当pushV[0] = 某一个值时会导致n=-1,所以n++,插入元素后也需要移动到下一位,移除某个元素后也需要利用该位置存储其他元素
        }
        return n==0;
}

新人学习代码,有问题欢迎随时评论交流,看到就会回复,谢谢大家。