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

C++ 数据结构:单调栈与单调队列总结

综述由AI生成C++ 数据结构中单调栈用于快速查找元素左侧或右侧第一个比它大或小的元素,单调队列则适用于滑动窗口最值问题。文章通过洛谷模板题 P5788 和 P1886 演示了两种结构的核心逻辑与代码实现,重点讲解了如何利用栈和双端队列维护单调性以优化时间复杂度。

栈溢出发布于 2026/3/23更新于 2026/5/128 浏览

单调栈

单调栈是具有单调性的栈(如递增、非递减),能提高解决特定问题的效率,例如找到某个元素左边或右边第一个比它大或小的元素。

应用(例题)

P5788 【模板】单调栈 - 洛谷

给出项数为 n 的整数数列 a1…n。定义函数 f(i) 代表数列中第 i 个元素之后第一个大于 ai 的元素的下标。若不存在,则 f(i)=0。试求出 f(1…n)。

解法

数据范围大,遍历不可行。需使用单调非递增栈。留在栈内的数是目前为止未找到大于自身元素的数。当新数进栈时,若栈顶元素小于它,说明找到了大于栈顶的数,弹出栈顶,重复直至条件不满足,最后压入当前数。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,f[4000050];
struct node{ ll val,pos; }a[4000050];
stack<node>sk;
void solve(node x){
    while(!sk.empty()){
        node y=sk.top();
        if(y.val<x.val){
            f[y.pos]=x.pos;
            sk.pop();
        }else break;
    }
    sk.push(x);
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].val;
        a[i].pos=i;
        solve(a[i]);
    }
    for(int i=1;i<=n;i++){
        cout<<f[i]<<' ';
    }
    return 0;
}

单调队列

单调队列是具有单调性的队列,同样能提高效率。

应用(例题)

P1886 【模板】单调队列 / 滑动窗口 - 洛谷

有一个长为 n 的序列 a,以及一个大小为 k 的窗口。窗口从左边向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最小值和最大值。

解法

数据范围大,遍历不可行。对于 min 值,队列应单调不递减。若新数比队尾小且更新,旧数无意义。进队前弹出队尾不满足单调性的元素。同时需检查队首元素是否超出窗口范围,若是则弹出。使用 deque 实现。max 值同理。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,bigg[1000050],smalll[1000050],k;
struct node{ ll val,pos; }a[1000050];
deque<node>q1,q2;
void big_solve(node x){
    while(!q1.empty()){
        node n1=q1.front();
        if(n1.pos<=x.pos-k)q1.pop_front();
        else break;
    }
    while(!q1.empty()){
        node n1=q1.back();
        if(n1.val<=x.val)q1.pop_back();
        else break;
    }
    q1.push_back(x);
    bigg[x.pos]=q1.front().val;
}
void small_solve(node x){
    while(!q2.empty()){
        node n1=q2.front();
        if(n1.pos<=x.pos-k)q2.pop_front();
        else break;
    }
    while(!q2.empty()){
        node n1=q2.back();
        if(n1.val>=x.val)q2.pop_back();
        else break;
    }
    q2.push_back(x);
    smalll[x.pos]=q2.front().val;
}
signed main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i].val;
        a[i].pos=i;
        big_solve(a[i]);
        small_solve(a[i]);
    }
    for(int i=k;i<=n;i++){
        cout<<smalll[i]<<' ';
    }
    cout<<endl;
    for(int i=k;i<=n;i++){
        cout<<bigg[i]<<' ';
    }
    return 0;
}

目录

  1. 单调栈
  2. 应用(例题)
  3. 解法
  4. 单调队列
  5. 应用(例题)
  6. 解法
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 前端流式输出技术:核心原理与实战方案
  • pytest Python 测试框架入门与实战指南
  • ZeroClaw Gateway + LM Studio + Reflex 本地 AI 管理面板搭建
  • OpenClaw 飞书机器人权限配置与安全指南
  • Capacitor 跨平台打包实战:Web 应用转原生 App
  • Redis Linux 安装与运行实战指南
  • 网络安全入门教程:从零开始掌握基础技术与工具
  • 6本AI领域名家名作推荐,大模型时代学习指南
  • 2025 年世界主流大模型编程能力排行
  • 低配电脑运行 AI 绘画的 GGUF 量化优化指南
  • Python 驱动的 ADS 自动化仿真框架与 API 实战指南
  • DGX Spark 部署 vLLM 与 Open WebUI 运行 Qwen3-Coder-Next-FP8 (CUDA 13.0)
  • DBeaver 社区版 AI 助手配置指南
  • 雷达信号处理:CFAR 恒虚警检测原理与 MATLAB 实战
  • JavaScript 文档对象(Document)核心属性实战解析
  • OpenClaw 智能体实战:从零搭建你的第一个 AI 员工
  • 二分算法实战:A-B 数对与烦恼的高考志愿
  • AI 辅助编程全面指南:技巧、策略与最佳实践
  • S3 与 HDFS:对象存储与分布式文件系统对比
  • C++ 智能指针完整详解

相关免费在线工具

  • 加密/解密文本

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

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,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