图解LeetCode——剑指 Offer 31. 栈的压入、弹出序列

简介: 图解LeetCode算法

一、题目

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

二、示例

2.1> 示例 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.2> 示例 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
  • pushedpopped 的排列。

三、解题思路

根据题目描述,我们会获得两个数组,一个是pushed数组,用于表示待入栈的元素及其入栈顺序;另一个是popped数组,表示出栈时元素的顺序。那么我们就可以通过这两个数组来模拟一下入栈和出栈的操作,那么如果执行完全部操作后,堆栈中已经没有任何元素的,则表示是符合题意的,我们就返回true;否则的话,我们就返回false了

那么根据以上的分析,我们需要创建一个堆栈数据结构,那么通常我们会选择Deque这个双向队列来模拟堆栈操作,当然也是可以选择Stack的,只是在提交后的执行效率会降低不少。

具体处理流程是这样的:我们创建指针j,指向popped数组的头部元素;然后从头开始遍历pushed数组;假设我们获取了pushed数组中的一个元素A,然后先将其放到堆栈中,之后进行如下判断逻辑:

栈顶元素等于popped[j] 】将栈顶元素弹出堆栈,并且将j指针向后移动一位(j++),重复执行这个操作,直到堆栈为空或者栈顶元素与popped[j]不同;

栈顶元素不等于popped[j] 】则不用做其他操作,继续遍历pushed数组中的其他元素即可。

如上就是这道题的解题思路了,下面我们还是举例来加深一下对这道题的理解。我们输入pushed = [1,2,3,4,5], popped = [4,5,3,2,1],如下就是具体的计算流程。请见下图所示:

四、代码实现

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Deque<Integer> deque = new ArrayDeque();
        int j = 0;
        for (int i = 0; i < pushed.length; i++) {
            deque.addLast(pushed[i]);
            while(!deque.isEmpty() && deque.peekLast() == popped[j]) {
                j++;
                deque.removeLast();
            }        
        }
        return deque.isEmpty();
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」


相关文章
|
5月前
|
存储 C++ 索引
最长连续序列(每天刷力扣hot100系列)
本题使用哈希表法求最长连续序列。利用unordered_set存储去重元素,遍历集合时仅当num-1不存在时才作为起点向后扩展,统计连续长度,时间复杂度O(n),空间复杂度O(n)。相比unordered_map更高效,因无需存储值。
|
9月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
377 1
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
209 6
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
118 0
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
116 0
|
算法 Python
【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
162 3
|
Python
【Leetcode刷题Python】剑指 Offer 32 - II. 从上到下打印二叉树 II
本文提供了一种Python实现方法,用于层次遍历二叉树并按层打印结果,每层节点按从左到右的顺序排列,每层打印到一行。
184 3
|
Python
【Leetcode刷题Python】剑指 Offer 32 - I. 从上到下打印二叉树
本文介绍了使用Python实现从上到下打印二叉树的解决方案,采用层次遍历的方法,利用队列进行节点的访问。
157 2
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
227 0
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
362 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行