跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

栈的压入弹出序列判断算法详解

针对给定的压栈序列和弹栈序列,验证后者是否合法。核心思路是利用辅助栈模拟入栈过程,每当栈顶元素与当前期望弹出的元素匹配时立即弹出。通过双指针遍历,时间复杂度为 O(n),空间复杂度同样为 O(n)。该方法适用于各类栈序列合法性校验场景,需特别注意空序列及长度不一致等边界条件。

念念不忘发布于 2026/3/280 浏览
栈的压入弹出序列判断算法详解

题目描述

给定两个整数序列:

  • pushV:压栈序列
  • popV:待验证的弹栈序列

需要判断 popV 是否可能是 pushV 对应的合法弹栈序列。

核心思路

要解决这个问题,关键在于理解栈的后进先出(LIFO)特性。我们需要模拟整个压栈和弹栈的过程:

  1. 压栈操作:元素按照 pushV 的顺序依次入栈。
  2. 弹栈操作:在任意时刻,只能弹出栈顶元素。
  3. 时机选择:可以在压入任意元素后,检查栈顶是否与当前期望弹出的元素匹配,若匹配则立即弹出。

这种贪心策略的核心在于:一旦栈顶元素与目标序列当前位置匹配,就必须弹出,因为后续再想弹出该元素必须先将其下方的元素弹出,这会导致顺序错乱。

完整代码实现

#include <vector>
#include <stack>
using namespace std;

class Solution {
public:
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
        // 使用辅助栈模拟压栈弹栈过程
        stack<int> st;
        
        // 双指针:_push 指向当前要压入的元素,_pop 指向当前要弹出的元素
        size_t _push = 0;
        size_t _pop = 0;
        
        // 遍历所有需要压入的元素
        while (_push < pushV.size()) {
            // 将当前元素压入栈中
            st.push(pushV[_push++]);
            
            // 检查栈顶元素是否与当前期望弹出的元素匹配
            // 如果匹配,则连续弹出所有匹配的元素
            while (!st.empty() && st.top() == popV[_pop]) {
                _pop++;
                st.pop();
            }
        }
        
        // 如果所有元素都能正确弹出,栈应该为空
        return st.empty();
    }
};

执行过程模拟

让我们通过一个具体例子来理解算法的执行逻辑:

示例输入:

  • pushV = [1, 2, 3, 4, 5]
  • popV = [4, 5, 3, 2, 1]

初始状态:栈为空,_push 指向 1,_pop 指向 4。

首先,我们按顺序压入元素 1、2、3。此时栈内为 [1, 2, 3],栈顶是 3,不等于目标值 4,继续压入。

压入 4 后,栈变为 [1, 2, 3, 4]。发现栈顶 4 与目标值 4 匹配,于是弹出 4,_pop 移动到 5。此时栈顶是 3,不匹配 5,继续压入。

压入 5 后,栈变为 [1, 2, 3, 5]。栈顶 5 匹配目标值 5,弹出 5,_pop 移动到 3。接着栈顶 3 匹配 3,弹出;栈顶 2 匹配 2,弹出;栈顶 1 匹配 1,弹出。

最终栈为空,说明序列合法,返回 true。

复杂度分析

时间复杂度

主循环遍历 pushV 中的每个元素一次。虽然内部有一个嵌套的 while 循环用于弹出元素,但每个元素最多被压入一次、弹出一次。因此,整体操作次数与序列长度 n 成正比,时间复杂度为 O(n)。

空间复杂度

需要一个辅助栈 st 来存储元素。最坏情况下(例如全部压入后才开始弹出),栈中会存储所有 n 个元素。因此,空间复杂度为 O(n)。

边界情况处理

在实际编码中,还需要考虑一些特殊场景:

  1. 空序列:如果两个序列都为空,通常视为合法匹配。
  2. 长度不一致:如果 pushV 和 popV 长度不同,直接判定为非法。
  3. 单元素序列:单个元素的匹配逻辑同样适用上述通用流程。

总结

这道题是考察栈特性的经典案例。通过引入辅助栈进行模拟,配合双指针技巧,我们可以高效地验证序列合法性。掌握这种'模拟 + 贪心'的思维方式,对于解决其他数据结构相关的算法问题也很有帮助。

目录

  1. 题目描述
  2. 核心思路
  3. 完整代码实现
  4. 执行过程模拟
  5. 复杂度分析
  6. 时间复杂度
  7. 空间复杂度
  8. 边界情况处理
  9. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • Spring Boot 集成 RabbitMQ 实战:从 Hello World 到生产级配置
  • 双指针算法实战:移动零与复写零详解
  • 使用 json-repair 库修复大模型返回的异常 JSON 格式
  • C++ STL list 容器详解:使用与模拟实现
  • OpenClaw 开源 AI 智能体框架技术解析与部署实践
  • OpenClaw 部署指南:Minimax/DeepSeek 模型与飞书机器人集成
  • MySQL 5.7 解压版安装与配置实战
  • MySQL 数据库基础入门:从概念到实战
  • MySQL 索引原理:B+ 树结构与实战优化
  • C++ 多态详解:从实现条件到底层原理
  • 位运算算法实战:6 道经典题目详解(字符唯一性、缺失数字等)
  • NC221681 dd 爱框框:滑动窗口算法实战
  • KingbaseES 内核级 SQL 防火墙:白名单机制与零误报实践
  • Flash 存储磨损均衡算法原理与实现
  • OpenClaw 汉化版部署指南:npm/Docker/脚本三种安装方式详解
  • PowerShell Invoke-WebRequest 报错 Invalid URL 和 CommandNotFound 排查指南
  • C++ 模板机制与 String 类深度解析
  • OpenClaw 部署与飞书机器人接入指南
  • C++ 哈希表封装:模拟实现 unordered_map 与 unordered_set
  • 无人机视角山区泥石流与滑坡图像识别数据集

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online