【牛客JZ31】—栈的压入弹出序列判断算法详解

【牛客JZ31】—栈的压入弹出序列判断算法详解
坚持用清晰易懂的图解+代码语言,让每个知识点变得简单!
🚀呆头个人主页详情
🌱 呆头个人Gitee代码仓库
📌 呆头详细专栏系列
座右铭:“不患无位,患所以立。”

【牛客JZ31】—栈的压入弹出序列判断算法详解


摘要


目录

题目描述

牛客链接直达----------请点击

给定两个整数序列:

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

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


核心思路

要解决这个问题,我们需要理解栈的工作机制:压栈操作:元素按照 pushV 的顺序依次入栈弹栈操作:在任意时刻,只能弹出栈顶元素时机选择:可以在压入任意元素后选择弹出栈顶元素

关键洞察:我们可以通过模拟整个压栈弹栈过程来验证序列的合法性。

完整代码实现

#include<vector>#include<stack>usingnamespace std;classSolution{public:boolIsPopOrder(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]
执行过程模拟
// 初始状态 stack<int> st;// 空栈 size_t _push =0;// 指向元素1 size_t _pop =0;// 指向元素4

第1轮循环

// 压入元素1 st.push(1);// 栈:[1] _push =1;// 指向元素2// 检查栈顶:1 != 4,不匹配,继续

第2轮循环

// 压入元素2 st.push(2);// 栈:[1, 2] _push =2;// 指向元素3// 检查栈顶:2 != 4,不匹配,继续

第3轮循环

// 压入元素3 st.push(3);// 栈:[1, 2, 3] _push =3;// 指向元素4// 检查栈顶:3 != 4,不匹配,继续

第4轮循环

// 压入元素4 st.push(4);// 栈:[1, 2, 3, 4] _push =4;// 指向元素5// 检查栈顶:4 == 4,匹配! st.pop();// 栈:[1, 2, 3] _pop =1;// 指向元素5

第5轮循环

// 压入元素5 st.push(5);// 栈:[1, 2, 3, 5] _push =5;// 超出范围// 检查栈顶:5 == 5,匹配! st.pop();// 栈:[1, 2, 3] _pop =2;// 指向元素3// 继续检查:3 == 3,匹配! st.pop();// 栈:[1, 2] _pop =3;// 指向元素2// 继续检查:2 == 2,匹配! st.pop();// 栈:[1] _pop =4;// 指向元素1// 继续检查:1 == 1,匹配! st.pop();// 栈:[] _pop =5;// 超出范围

最终结果:栈为空,返回 true


算法复杂度分析

时间复杂度

// 主循环:遍历pushV中的每个元素while(_push < pushV.size()){// O(n) st.push(pushV[_push++]);// O(1)// 内层循环:每个元素最多被弹出一次while(!st.empty()&& st.top()== popV[_pop]){// 总计O(n) _pop++; st.pop();}}
  • 外层循环:执行 n 次(n 为序列长度)
  • 内层循环:虽然是嵌套循环,但每个元素最多被压入和弹出各一次
  • 总时间复杂度:O(n)

空间复杂度

stack<int> st;// 辅助栈,最坏情况下存储所有元素
  • 辅助栈空间:最坏情况下需要存储所有 n 个元素
  • 总空间复杂度:O(n)

边界情况处理

空序列处理

boolIsPopOrder(vector<int>& pushV, vector<int>& popV){// 如果两个序列长度不同,直接返回falseif(pushV.size()!= popV.size()){returnfalse;}// 空序列的情况if(pushV.empty()){returntrue;// 两个空序列匹配}// 原算法逻辑...}

单元素序列

// 测试用例 vector<int> pushV ={1}; vector<int> popV ={1};// 结果:true vector<int> pushV2 ={1}; vector<int> popV2 ={2};// 结果:false

总结

通过这道题的分析,我们深入理解了以下几个重要概念:

  1. 栈的模拟:通过辅助栈来模拟实际的压栈弹栈过程
  2. 双指针技巧:使用两个指针分别跟踪压栈和弹栈的进度
  3. 贪心策略:每当栈顶元素与期望弹出元素匹配时,立即弹出
  4. 算法验证:通过最终栈是否为空来验证序列的合法性

这种模拟法不仅适用于栈的相关问题,在很多其他算法场景中也有广泛应用。掌握这种思维方式,对于提升算法设计能力具有重要意义。


参考链接

  1. LeetCode 946. 验证栈序列
  2. 牛客网 - 栈的压入、弹出序列
  3. 数据结构与算法 - 栈的应用
  4. C++ STL stack 容器详解
  5. 算法导论 - 栈和队列

关键词标签

栈数据结构算法模拟双指针C++STL

Read more

OpenCode 免费模型深度评测:四大开源模型场景化对比与选型指南

OpenCode 免费模型深度评测:四大开源模型场景化对比与选型指南

在开源大语言模型(LLM)生态中,OpenCode 凭借其多样化的免费模型矩阵(如 Trinity Large Preview、Big Pickle、MiniMax M2.5 Free、GPT-5 Nano)吸引了开发者与企业的广泛关注。本文将从技术架构、性能表现、适用场景等维度,深度解析这四大模型的差异化优势,并提供选型建议。 1. Trinity Large Preview:超大规模稀疏模型的“创意引擎” 开发者:Arcee AI 核心架构:400B 参数稀疏混合专家(MoE)架构,每 token 仅激活 13B 参数 上下文窗口:512K tokens(约 75 万字) 适用场景:创意写作、

By Ne0inhk
【工创赛2025-智能物流搬运塔吊方案视觉开源(2分15秒)】西安理工大学工程训练中心

【工创赛2025-智能物流搬运塔吊方案视觉开源(2分15秒)】西安理工大学工程训练中心

一、前言         本文也是我的第一篇ZEEKLOG博客,主要内容是记录一下2025年工训赛的参赛过程,讲解一下与louisaerdusai学长一起开发的智能物流视觉方案。主要内容为:实现函数、串口与下位机的通讯和整个实现流程,希望我们的经验能够帮助大家。         本文为视觉算法开源,其他部分开源请移步:【工创赛2025-塔吊结构方案开源(2分15秒)】西安理工大学工程训练中心-ZEEKLOG博客 二、本届视觉设计由来         我在今年校赛阶段参加的是智能救援赛道,由于我们机械设计的过于复杂和一些其他原因,机械结构的反复修改,最终没有尽快实现视觉与机械结构联调,导致我们在校赛就遗憾出局。在校赛遗憾结束后,我有幸加入了学长的队伍,在重新了解了物流搬运的视觉流程后,发现使用Jetson Nano运行OpenCV算法算是更加灵活的选择。但是在省赛是我也发现很多队伍采用的OpenMV方案也可以流畅运行,就我使用这些微型视觉模块的经验来说,我推荐使用MaixCAM pro来实现简单的算法,但是不得不说OpenCV的算法实现是更加通用且灵活的,同时使用OpenCV算

By Ne0inhk
git笔记之默认使用vim以及修改倒数第二次的commit提交信息到远程

git笔记之默认使用vim以及修改倒数第二次的commit提交信息到远程

git笔记之默认使用vim以及修改倒数第二次的commit提交信息到远程 code review! 文章目录 * git笔记之默认使用vim以及修改倒数第二次的commit提交信息到远程 * 一.默认使用vim方法之一:使用 `git config` 命令 * 二.修改倒数第二次的commit提交信息到远程 * 操作步骤 * 第一步:启动交互式变基 (Interactive Rebase) * 第二步:选择要修改的提交 * 第三步:修改提交信息 * 第四步:强制推送到远程 * 总结流程图 * 常见问题:如果在 Rebase 过程中遇到冲突怎么办? 一.默认使用vim方法之一:使用 git config 命令 这是最直接且专门针对 Git 的设置方法。打开的终端(Terminal)或 Git Bash,运行以下命令: git config --global core.editor "

By Ne0inhk

OpenClaw 最新功能大揭秘!2026年最火开源AI Agent迎来史诗级升级,手机变身AI终端不是梦

OpenClaw 最新功能大揭秘!2026年最火开源AI Agent迎来史诗级升级,手机变身AI终端不是梦 大家好,我是Maynor。最近开源社区彻底炸锅了——OpenClaw(前身Clawdbot/Moltbot)又一次刷屏!这个能真正“干活”的本地AI助手,在3月2日刚刚发布v2026.3.1版本,紧接着2月底的v2026.2.26也是里程碑式更新。 从外部密钥管理、线程绑定Agent,到Android深度集成、WebSocket优先传输……OpenClaw正在把“AI常驻员工”从概念变成现实。 今天这篇图文并茂的干货,带你一口气看懂最新功能、安装上手和实战价值!

By Ne0inhk