一、题目描述
题目链接:力扣 946. 验证栈序列
题目描述:
给定两个整数数组 pushed 和 popped,其中 pushed 是入栈顺序,判断 popped 是否为合法的出栈顺序。
示例 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 之前弹出。
提示: 1 <= pushed.length <= 1000 0 <= pushed[i] <= 1000 pushed 的所有元素互不相同 popped.length == pushed.length popped 是 pushed 的一个排列
二、为什么这道题值得你花几分钟弄懂?
这道题是栈结构基础应用的标杆题,也是面试中'考察数据结构核心思想'的高频题。它没有复杂的语法陷阱,却能精准检验我们是否真正理解栈'后进先出(LIFO)'的核心特性,是夯实栈基础的必做题。
题目核心价值
- 栈本质的'试金石':不考复杂 API,只考栈的核心规则——入栈出栈的顺序逻辑。提到栈我们都先想到的就是'后进先出'的定义,如果在这道题上卡壳那就是因为我们没把定义转化为可执行的操作逻辑。
- 模拟思维的训练场:解题核心是'模拟真实栈操作',这种'还原执行过程'的思维,是解决所有数据结构应用题的通用思路。掌握它,后续遇到队列、链表的模拟题都能快速上手。
- 面试的'基础筛选题':大厂面试常把它当作'暖场题',考察候选人的基础逻辑。能快速写出简洁解法,说明数据结构基础扎实;反之,只会死记硬背的短板会被直接暴露。
- 边界场景的考量:它覆盖了'全入栈后出栈''边入边出''部分入栈即出栈'等所有栈操作场景,能训练我们考虑问题的全面性,避免因忽略极端情况导致代码漏洞。
- 代码简洁性的体现:最优解法仅需几行核心代码,能考察我们'用最少代码实现核心逻辑'的能力,完全契合面试中'代码简洁性'的评分标准。
面试考察的核心方向
- 栈特性的理解深度:能否说清'后进先出'如何体现在入栈出栈序列验证中,而非单纯复述定义。
- 模拟思维的落地能力:能否将'手动验证栈序列'的过程转化为代码逻辑,这是'想得到'和'写得出'的分水岭。
- 代码的简洁性与可读性:最优解法逻辑清晰、代码短小,能体现你的编码风格和逻辑抽象能力。
- 复杂度分析的准确性:能否快速分析出时间/空间复杂度,理解'模拟操作'的代价,这是区分初级和进阶开发者的关键。
掌握这道题,既能彻底吃透栈的核心规则,又能训练'模拟执行'的解题思维。后续遇到栈相关的进阶题,比如表达式计算、括号匹配,都能快速找到解题思路,性价比极高。
三、题目解析
力扣中这道题的题干机翻的已经非人类了,但这道题要考察的其实就是我们在数据结构考试中很熟悉的题型——给一个入栈序列和一个出栈序列,判断后者是否合法。
核心问题可以简化为:按照 pushed 的顺序把元素一个个放进栈里,能不能在任意时刻弹出栈顶元素,最终得到的弹出顺序和 popped 完全一致?
这个问题的答案,就藏在栈'后进先出'的规则里——只有栈顶的元素,才有权被弹出。
四、算法原理
本题核心算法是 '模拟栈操作',完全还原真实的入栈出栈过程,用'实际操作'验证序列合法性。思路简单且高效,和我们手动做这类题的思路完全一致。
如何解决问题?
- 我们在手动做题目的时候脑海中自动的为我们准备一个,我们会按照 序列的顺序,把元素逐个入栈。


