2023年5月3日 单调栈及其应用

news2024/11/18 19:34:56

文章目录

  • 单调栈的应用
    • [830. 单调栈 - AcWing题库](https://www.acwing.com/problem/content/description/832/)
    • [P5788 【模板】单调栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](https://www.luogu.com.cn/problem/P5788)
    • [84. 柱状图中最大的矩形 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/)
      • 思路一
      • Code
      • 思路二
      • Code
    • [1575. 盛水最多的容器 - AcWing题库](https://www.acwing.com/problem/content/1577/)
      • 双指针算法
    • [1574. 接雨水 - AcWing题库](https://www.acwing.com/problem/content/description/1576/)
      • 双指针算法

单调栈的应用

可以用来快速找出左右第一个比 a i a_i ai大或小的数及其下标

830. 单调栈 - AcWing题库

给定一个长度为 N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。
Code 如下:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N =  100010;

int n;
int stk[N],tt;

int main()
{
    
    cin>>n;
    
    for (int i = 0; i < n; i ++ )// 输出左边第一个比他小的数。 
    {
        int x;
        cin >> x;
        while(tt && stk[tt] >= x) tt--;// 栈是非空的,且栈顶元素大于x, 栈顶弹出。
        if(tt) cout << stk[tt] << ' ';
        else
        cout<<-1 <<' ';
        stk[++tt] = x;
    }
   
    return 0;
}
# 读取数组
n = int(input())
nums = list(map(int, input().split()))

# 单调栈
deq = []

# 开始处理数据
for i in range(len(nums)):

    # 从单调栈中弹出不满足升序的数
    while deq and deq[-1] >= nums[i]:
        deq.pop()

    # 此时要么栈空(没有最小),否则栈顶元素就是最近的最小元素
    if len(deq) != 0:
        print(deq[-1], end = " ") 
    else:
        print(-1, end = " ")

    # 将当前数据加入单调栈中(当前数据一定能够保证单调栈升序)
    deq.append(nums[i])

P5788 【模板】单调栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int N = 3e6+10;

int f[N],a[N];// f 答案, a是原始数组, 
stack<int> s;//s是单调栈。
int n,tt;

int main()
{
    scanf("%d", &n);
    
    for (int i = 1; i <= n; i ++ )scanf("%d", &a[i]);
    for (int i = n; i >= 1; i -- )// 输出右边第一大于a【i】 的下标
    {
        while(!s.empty() && a[s.top()] <= a[i]) s.pop();// 如果栈不为空, 且栈顶元素小于a[i], 则弹出
        f[i] = s.empty()? 0 : s.top();
        s.push(i);
    }
    for (int i = 1; i <= n; i ++ )printf("%d ",f[i]);
    return 0;
}

84. 柱状图中最大的矩形 - 力扣(LeetCode) (leetcode-cn.com)

思路一

Code

class Solution {
public:
    int largestRectangleArea(vector<int>& h) {
        stack<int> stk;
        int n = h.size();
        if(n == 1) return h[0];
        int ans = 0;
        int left[n], right[n];
        // 左边第一个比h[i]小的下标letf[i]中;右边第一个比h[i]小的下标right[i]中;
        for(int i = 0; i < n; i++)
        {
            while(!stk.empty() && h[stk.top()] >= h[i])stk.pop();
            if(stk.empty())left[i] = -1;
            else left[i] = stk.top();   
            stk.push(i);
        } 
        stk = stack<int>(); // 清空stk;
        for(int i = n-1; i >= 0 ;  i--)
        {
            while(!stk.empty() && h[stk.top()]>=h[i]) stk.pop();
            if(stk.empty()) right[i] = n;
            else right[i] = stk.top();    
            stk.push(i);
        }

        for(int i = 0 ; i<n; i++)
        {
            ans = max(ans, h[i]*(right[i]-left[i]-1));
        }
        return ans;
    }
};

思路二

Code

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.push_back(-1);
        //加入哨兵值,便于原先heights中的最后位置的值弹出
        //因为需要比最后一个值小的值,才能把最后一个值卡在
        //中间计算面积
        stack<int>  stacks;
        stacks.push(-1);
        //栈压入哨兵值,便于heights打头的数组进行操作
        //压入-1为方便计算打头位置的面积
        int   maxs = 0;
        for(int  i=0;i<heights.size();i++)
        {
            while(stacks.top() != -1&&heights[stacks.top()] > heights[i])
            //栈里面后面比前面大的时候才压入,相当于顺序压入,当
            //当前值比栈顶的值小的时候,相当于两个比栈顶小的值把
            //栈顶位置的数卡在中间,比如5,6,2,栈顶数为6
            //此时可以计算栈顶6围成的矩形面积
            {
                int  nums = stacks.top();
                stacks.pop();
                maxs = max(maxs,heights[nums]*(i-stacks.top()-1));
                //面积计算公式为当前下标值*(左右两边的坐标减去1)
            }
            stacks.push(i);
            //栈前面都为比当前值小的时候,无法将栈顶值卡在中间了
            //此时压入当前坐标
        }
        return  maxs;
    }
};

优化思路2

class Solution {
public:
    int largestRectangleArea(vector<int>& h) {
        stack<int> stk;
        h.push_back(-1); // 为了能让栈清空。 在数组后面放一个-1.
        int n = h.size();
        int ans = 0;
        for(int i = 0; i <n; i++)
        {
            while(stk.size() && h[i]<h[stk.top()]) 
            {
                int idx = stk.top();
                stk.pop(); 
                int left = stk.empty()? -1 : stk.top();// 比h[idx]小的左边的第一数的下标。 
                ans = max(ans, (i- left - 1 )* h[idx]);
            }
            stk.push(i);
        }
        return ans;
        
    }
};

1575. 盛水最多的容器 - AcWing题库

双指针算法

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int a[100100];

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &a[i]);
    }
    int ans = 0,l = 1,r = n;
   
    while(l<r)
    {
        ans = max(ans,(r-l)*min(a[r],a[l]));
        if(a[l]<a[r]) l++;
        else r--;
    }
    cout << ans;
    return 0;
}

1574. 接雨水 - AcWing题库

双指针算法

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e5+10;
int pre_max[N], suf_max[N], h[N],n;

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &h[i]);
        pre_max[i] = max(pre_max[i-1], h[i]);
    }
    
    for (int i = n; i >= 0; i -- )
    {
        suf_max[i]= max(suf_max[i+1],h[i]);
    }
    int ans =0;
    for (int i = 1; i <= n; i ++ )
    {
        ans += min(pre_max[i],suf_max[i]) - h[i];
    }
    cout << ans;
    
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/485355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatGPT的翻译能力如何-GPT批量翻译软件

ChatGPT翻译软件 如果您正在为翻译工作而烦恼&#xff0c;或者需要面对语种广泛的国际化业务&#xff0c;那么ChatGPT翻译软件是您的不二之选。 ChatGPT翻译软件基于自然语言处理技术&#xff0c;利用先进的机器学习算法和深度神经网络模型&#xff0c;能够快速、高效地进行多…

将Egg项目部署到阿里云服务器

目录 1、连接阿里云服务器&#xff0c;上传文件 2、在阿里云服务器上安装Nodejs 3、下载项目依赖 4、安装 egg-scripts 模块 5、启动项目 6、阿里云服务器开启7001端口 1、连接阿里云服务器&#xff0c;上传文件 推荐使用FileZilla Client工具连接云服务器&#xff0c;可…

基于蝴蝶算法的极限学习机(ELM)回归预测-附代码

基于蝴蝶算法的极限学习机(ELM)回归预测 文章目录 基于蝴蝶算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于蝴蝶算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用蝴蝶算法对极限学习机进行优化&#xff0c;并…

LVS+Keepalived 高可用群集部署

一、LVSKeepalived 高可用群集 在这个高度信息化的 IT 时代&#xff0c;企业的生产系统、业务运营、销售和支持&#xff0c;以及日常管理等环节越来越依赖于计算机信息和服务&#xff0c;对高可用&#xff08;HA&#xff09;技术的应用需求不断提高&#xff0c;以便提供持续的…

[Git] Git零基础?带你快速入门,示例练习上手

&#x1f61a;一个不甘平凡的普通人&#xff0c;致力于为Golang社区和算法学习做出贡献&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;算法学习 &am…

STL--list

一、list介绍 列表是序列容器&#xff0c;允许在序列内的任何位置执行恒定时间插入和擦除操作&#xff0c;以及双向迭代 列表容器作为双向链表实现;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个和后一个元素 它们与forward_list非常…

3.rabbitMQ之发布确认高级和整合springboot(重要)找了很多博客整理出来的

1.极端情况下 rabbitMQ需要重启,导致消息投递失败(生产者发消息全部丢失)(交换机或者队列出问题) 生产者需要把数据放到缓存,用定时任务重新发送 解决方法: 0.必须配置文件写 spring.rabbitmq.publisher-confirm-typecorrelatedspring.rabbitmq.publisher-returnstruecorrelati…

appuploader 入门使用

回想一下我们发布 iOS 应用&#xff0c;不仅步骤繁琐&#xff0c;非常耗时。一旦其中一步失误了&#xff0c;又得重新来。作为一名优秀的工程师不应该让这些重复的工作在浪费我们的人生。在软件工程里面&#xff0c;我们一直都推崇把重复、流程化的工作交给程序完成。这次的文章…

【shell脚本】for循环语句

循环语句与函数 一、循环与遍历1.1循环1.2遍历1.3循环与遍历 二、for循环2.1for循环的基本格式2.2for循环小实验2.3双层for循环实验 三、while循环3.1 while格式 四、跳出循环4.1continue跳出循环实验4.2break跳出循环实验 一、循环与遍历 1.1循环 循环 (Loop) 是计算机编程中…

不会前端,怎么快速打造属于自己的个人博客?

个人博客 简介提前准备 一、初始化vuepress项目二、页面配置首页配置顶部配置顶部导航栏路由配置侧边导航栏配置 三、打包部署四、数据统计插槽自定义插槽配置整体结构页面效果 项目地址 简介 主要教大家如何快速搞一个属于自己的博客网站&#xff0c;特别是一些不怎么会前端的…

【C++】——类与对象(上)

文章目录 1. 前言2. 面向过程和面向对象3. 类的引入4. 类的定义4.1 类的俩种定义方式 5. 类的访问限定符及封装5.1 类的访问限定符5.2 封装 6. 类的作用域7. 类的实例化8. 类对象的存储方式9. this指针9.1 this指针特性 10. 结尾 1. 前言 今天我们来学习C初期最重要的知识点&a…

用于无线传感器网络路由的改进leach协议(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 当前&#xff0c;无线传感器由于技术的发展得到更加广泛的应用&#xff0c;针对无线传感器网络&#xff08;WSN&#xff09;的…

linux重装mmsegmentation

前言 换了个电脑&#xff0c;就想着把之前的mmsegmentation-V0.26.0代码放到新环境&#xff0c;结果踩了不少坑~ 过程 官方步骤 0 安装miniconda 1 创建conda 环境 最开始用的是python3.10&#xff0c;后来发现版本太高不是一件好事&#xff0c;所以装的python3.8 2 安装…

FineBI 6.0入门基础(二)

在图形中分析 组件还可以进行复制,如下图 复制后,切换为【自定义图表】 1.将【毛利额】调整为折线(在图形属性里面进行调整) 2.由于【毛利额】和【毛利额环比增长率】数值差距较大,可将指标中的【毛利额环比增长率】调整为右值轴 3.将图例调整显示位置(组件样式-图例…

ZooKeeper 避坑指南: ZooKeeper 3.6.4 版本 BUG 导致的数据不一致问题

作者&#xff1a;子葵 背景 ZooKeeper 作为分布式系统的元数据中心&#xff0c;对外服务的数据一致性需要得到很好的保证&#xff0c;但是一些老版本的 ZooKeeper 在一些情况下可能无法保证数据的一致性&#xff0c;导致依赖 ZooKeeper 的系统出现异常。 某用户使用 3.4.6 版…

回归问题(AI笔记)

人工智能 回归问题 1943 年&#xff0c;心理学家沃伦麦卡洛克 (Warren McCulloch)和数理逻辑学家沃尔特皮茨(Walter Pitts)通过对生物神经元的研究&#xff0c; 提出了模拟生物神经元机制的人工神经网络的数学模型 &#xff0c;这一成果被美国神经学家弗 兰克罗森布拉特(Frank …

(别再手动点APP了)UiAutomator2自动化测试框架带你玩转APP操作

目录 前言 一、uiautomator/uiautomator2的前生今世 1.官方文档介绍 2.梳理一下脉络 3.三款框架对比 二、uiautomator2简介 1.项目组成 2.工作原理 三、环境搭建 1.安装uiautomator2 2.初始化设备 3.init时都干了啥&#xff1f; 四、基础操作 1.连接设备 2.命令…

手把手教你搭建 Webpack 5 + React 项目

前言 在平时工作中&#xff0c;为减少开发成本&#xff0c;一般都会使用脚手架来进行开发&#xff0c;比如 create-react-app。脚手架都会帮我们配置好了 webpack&#xff0c;但如果想自己搭建 webpack 项目要怎么做呢&#xff1f;这边文章将介绍如何使用 webpack 5 来搭建 re…

HNU-操作系统OS-实验Lab2

OS_Lab2_Experimental report 湖南大学信息科学与工程学院 计科 210X wolf &#xff08;学号 202108010XXX&#xff09; 前言 实验一过后大家做出来了一个可以启动的系统&#xff0c;实验二主要涉及操作系统的物理内存管理。操作系统为了使用内存&#xff0c;还需高效地管理…

C++全栈知识体系 2.0

C 全栈知识体系 一个记录C知识的学习网站&#xff01; 包含内容: C(基础、函数、知识点、IO框架、新特性), 算法, 数据库(MySQL、ElasticSearch、Redis), 编程四大件, 架构, 微服务, 中间件(ZeroMQ、Dubbo、Consul、Logstash、Kong), 工具, 部署(Docker、k8s、Istio), 项目(开源…