【剑指offer】31. 栈的压入、弹出序列

89 阅读2分钟

题目描述

在这里插入图片描述 在这里插入图片描述

// 31. 栈的压入、弹出序列

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


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

题解

// 题目还是有一定难度的
// 需要直接按照题目意思模拟:
// 双指针pop序列和push序列一起遍历,push在前,如果push的元素正好等
// 于pop的元素,则push之后直接pop,如果不相等,压入栈,push指针右移,
// 继续判断。push序列遍历完不能停止,pop序列还要继续遍历,直到栈存储
// 的元素全部弹出,栈中存在弹不出的元素,就返回false了。全部弹出则返
// 回true。

在这里插入图片描述

// 力扣
// 比较好理解
// 执行用时:2 ms, 在所有 Java 提交中击败了94.50%的用户
// 内存消耗:38 MB, 在所有 Java 提交中击败了81.85%的用户
import java.util.Stack;
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        if (pushed.length == 0 && popped.length == 0) 
            return true;
        if (pushed.length == 0 || popped.length == 0)  // 排除特殊情况
            return false;
        int i = 0, j = 0;  // 索引 for push and pop
        Stack<Integer> sim = new Stack<>();
		// 直到popped指针走完再停止while(弹出操作执行完再停止while)
        while (j < popped.length) {
            // System.out.println(sim.toString());
			// 如果栈顶元素等于弹出序列popped的遍历元素
            if (!sim.isEmpty() && sim.peek() == popped[j]) {  
                sim.pop();  // 弹出
                j++;  // 指针右移
            }
            else if (i < pushed.length && pushed[i] == popped[j]) {
                sim.push(pushed[i++]);  // push遍历元素和pop遍历元素相等
                sim.pop();  // 压入再弹出,两个指针右移
                j++;
            }
            else if (i < pushed.length) {  // 如果没有可弹出元素,
                sim.push(pushed[i++]);  // 压入元素,指针右移
            }
            else  // 如果元素全部压入栈了,又没有可弹出元素,直接false
                return false;
        }
        return sim.isEmpty();
   }
}

// 力扣
// 稍微精简
import java.util.Stack;
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int i = 0, j = 0;  // for push and pop
        Stack<Integer> sim = new Stack<>();
        while (j < popped.length) {
            // System.out.println(sim.toString());
            if (!sim.isEmpty() && sim.peek() == popped[j]) {
                sim.pop();
                j++;
            }
            else if (i < pushed.length && pushed[i] == popped[j]) {
				i++;
                j++;
            }
            else if (i < pushed.length) {
                sim.push(pushed[i++]);
            }
            else 
                return false;
        }
		return sim.isEmpty();
   }
}


// 力扣
// 逻辑合并一下
// 执行用时:2 ms, 在所有 Java 提交中击败了94.50%的用户
// 内存消耗:38.3 MB, 在所有 Java 提交中击败了36.81%的用户
import java.util.Stack;
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int i = 0, j = 0;  // for push and pop
        Stack<Integer> sim = new Stack<>();
        while (i < pushed.length) {
			// System.out.println(sim.toString());
			sim.push(pushed[i++]);
            while (j < popped.length && !sim.isEmpty() && sim.peek() == popped[j]) {
                sim.pop();
                j++;
            }
        }
        return sim.isEmpty();
   }
}


// 牛客
// 运行时间:11ms
// 占用内存:9668k
import java.util.Stack;
public class Solution {
	public boolean IsPopOrder(int[] pushA, int[] popA) {
		int i = 0, j = 0;
		Stack<Integer> sim = new Stack<>();
		while (i < pushA.length) {
			sim.push(pushA[i++]);
			while (j < popA.length && !sim.isEmpty() && sim.peek() == popA[j]) {
				sim.pop();
				j++;
			}
		}
		return sim.isEmpty();
	}
}