剑指 Offer 31. 栈的压入、弹出序列

题目描述

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

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

提示:

0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed 是 popped 的排列。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

模拟入栈和出栈

先创建一个栈,把入栈序列压入栈中,不过不是一次性全部压入,因为可能会先弹出一些元素,再压入元素

压入一个元素之后,就判断当前栈顶元素与popped序列的当前元素是否相等,不相等,则继续压入元素,如果相等,则弹出栈顶元素,同时,应该有一个变量记录当前判断到popped序列的哪一个元素了

继续循环判断当期栈顶元素与popped序列的当前元素是否相等,不满足循环条件就继续压入元素,直到pushed序列都已经压入到栈中

最后判断当前栈是否为空,如果popped序列是pushed序列的弹出序列,则当前栈应该为空。

在这里插入图片描述

代码

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
         Stack<Integer> stack=new Stack();
         int count=0;
         for(int i=0;i<pushed.length;i++)
         {
             stack.push(pushed[i]);//模拟入栈
             while(!stack.empty()&&stack.peek().intValue()==popped[count])//模拟出栈,当当前栈顶元素和popped[count]相等,就出栈
             {//这里用while循环的原因是可能出栈一个元素之后,  count++; ,当前栈的栈顶元素依然等于popped[count]
             //如果只用if,则for循环结束,程序也就结束了        
               int k=stack.pop();
               //System.out.println(k);
               count++;  
             }
         }
         return  stack.empty();//栈为空,说明入栈序列按照出栈序列都弹出了,如果栈不为空,说明给定的popped序列不是入栈序列的弹出序列
    }
}

在这里插入图片描述

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack = new Stack<>();
        int i = 0;
        for(int num : pushed) {
            stack.push(num); // num 入栈
            while(!stack.isEmpty() && stack.peek() == popped[i]) { // 循环判断与出栈
                stack.pop();
                i++;
            }
        }
        return stack.isEmpty();
    }
}


作者:jyd
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/mian-shi-ti-31-zhan-de-ya-ru-dan-chu-xu-lie-mo-n-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

模拟

class Solution {
    /* // 模拟 */
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int n = pushed.length;
        // 设置一个栈模拟出栈入栈行为
        Stack<Integer> s = new Stack<>();
        // 逐个检查能否得到popped出栈序列
        for (int i = 0, j = 0; j < n;) {
            // 若栈顶元素不是当前popped序列所处理的那个或栈空,那就从pushed序列取元素入栈
            while (i < n && (s.empty() || s.peek() != popped[j]))
                s.push(pushed[i++]);
            // 如果出栈序列用完了都得不到出栈序列元素,说明pushed的入栈顺序不可能得到popped的出栈顺序
            if (i == n && s.peek() != popped[j])
                return false;
            while (!s.empty() && s.peek() == popped[j]) {
                s.pop();
                ++j;
            }
        }
        return true;
    }
}


作者:meteordream
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/jian-zhi-31zhan-de-ya-ru-dan-chu-xu-lie-heedx/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

空间优化+模拟

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

下面这个代码可能得结合上面的模拟代码才能看懂

class Solution {
    /* // 模拟 + 空间压缩 */
    // 注意到我们设置用于模拟的栈大小不会超出pushed的大小,且pushed和popped的元素都只需遍历一次就行,那么我们可以在pushed上原地进行模拟,其余思路不变
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int n = pushed.length;
        // pushed 已经遍历过的位置设置一个模拟栈的栈顶指针
        int s = 0;
        // 逐个检查能否得到popped出栈序列
        for (int i = 0, j = 0; j < n;) {
            // 若栈顶元素不是当前popped序列所处理的那个或栈空,那就从pushed序列取元素入栈
            while (i < n && (s == 0 || pushed[s - 1] != popped[j]))
            //s-1是因为压入一个元素之后,s加了1表示当前栈中的元素个数,取栈顶肯定是s-1呀,s还没放元素呢
                pushed[s++] = pushed[i++];
            // 如果出栈序列用完了都得不到出栈序列元素,说明pushed的入栈顺序不可能得到popped的出栈顺序
            if (i == n && pushed[s - 1] != popped[j])
                return false;
            while (s > 0 && pushed[s - 1] == popped[j]) {
                --s;
                ++j;
            }
        }
        return true;
    }
}


作者:meteordream
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/jian-zhi-31zhan-de-ya-ru-dan-chu-xu-lie-heedx/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考

面试题31. 栈的压入、弹出序列(模拟,清晰图解)
[剑指31.栈的压入、弹出序列] 模拟及空间优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值