单调栈和单调队列浅谈

参考:
https://blog.csdn.net/zuzhiang/article/details/78134247
https://wenku.baidu.com/view/ec3278ae2f60ddccda38a0f5.html
https://blog.csdn.net/Prasnip_/article/details/83690038
https://blog.csdn.net/ljd201724114126/article/details/80663855

单调栈可以解决:

①可以方便的求出某个数的左边或者右边第一个比它大或者小的元素,总时间复杂度为O(n)。
如何维护:
进栈操作:每次入栈前先检查栈顶元素和进栈元素(x)的大小,如果小于x,就让x直接入栈。如果栈顶元素大于等于x,那么出栈,直到栈空或者栈顶元素小于x。
例题:(POJ 2559)
给出一个柱形统计图,输入宽度为1的矩形的高度,求出这个柱形图中的最大面积的长方形(n<=le5)
例如:2,1,4,5,1,3,3 最打面积为8
在这里插入图片描述
那么如何使用单调栈求解这个呢?
我们可以知道最终的结果是一定是: 在某个区域内,最低矩形的高度x,答案就是x*矩形个数。
那么如何计算x左边的矩形数和x右边的矩形数呢?单调有个left[x]和right[x]数组分别表示x的左边比他大的个数(如果中途出现比x小的就不往左了),和右边比他大的个数(同样如果中途出现比x小的就不往右了),那么就可以解决这个问题了。
具体看代码:
该程序单调栈大致的流程:
每个节点存两个值,一个权值,一个表示第几个数
单调栈中的数都是单调的(这里以单调非递减为例)
当搞完n个数后,还需在最后在压入一个小于题目要求的数,以便将所有数都弹出来。
主要思路:
遍历某个数时,
1.栈空,入队
2.栈不为空,
 若大于栈顶元素,直接压入;
 否则,将栈顶元素弹掉,直到栈顶元素<=这个数
(在弹的过程中进行操作,依具体题目而定)

// #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
#define ll long long
#define p pair<ll , ll>
const int N=1e5+100;;
ll lef[N]; // left[x]以a[x]为矩形的最小的高度的的区域的最左边所在的位置
ll right[N]; // right[x] 表示以a[x]为矩形的最小的高度的的区域的最右边所在的位置
stack<p> sta; // p a的一个数存数据大小,后一个数表示是第几个数
ll a[N];//存放数据
ll solve(int n)
{
   
	ll ans=0;
	for(int i=0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值