算法竞赛进阶指南——0x11【栈】


在这里插入图片描述

模拟栈

栈的入栈、出栈、返回栈顶、返回栈的最小值的操作
【用一个数组和变量(记录栈顶位置)实现栈结构】

class Solution
{
private:
    int a[100000], minn[100000];
    int size =0;
public:
    void push(int value)
    {
        a[size] = value;
        if (size == 0)
            minn[0] = value;
        else
            minn[size] = minn[size-1] < value ? minn[size-1] : value;
        size++;
    }
    void pop()
    {
        size--;
    }
    int top()
    {
        if (size)
            return a[size-1];
        exit(1);
    }
    int min()
    {
        if (size)
            return minn[size-1];
        exit(1);
    }
};

表达式计算

单调栈

牛客一个小栗子Largest Rectangle in a Histogram

单调栈处理问题的思想在于及时排除不可能的选项,保持策略集合的高度有效性和秩序性

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;
ll n;
ll a[N], st[N], w[N], ans;
int main()
{
    while (scanf("%lld", &n) && n != 0)
    {
        memset(a, 0, sizeof(a));
        ans = 0;
        for (ll i = 1; i <= n; i++)
            scanf("%lld", &a[i]);
        ll p = 0;
        a[n + 1] = 0;                   //最后要整个出栈,所以认为a[0]=a[n+1]=0;
        for (ll i = 1; i <= n + 1; i++) //单调栈算法
        {
            if (a[i] >= st[p]) //单调递增栈
            {
                st[++p] = a[i]; //入栈
                w[p] = 1;
            }
            else
            {
                ll width = 0;
                while (a[i] < st[p])
                {
                    width += w[p];                 //累计宽度
                    ans = max(ans, width * st[p]); //更新答案
                    p--;                           //出栈
                }
                st[++p] = a[i];   //入栈
                w[p] = width + 1; //最终的单增栈里面每个数的w[j]表示与左边比它小的第一个数之间,有w[j]-w[i]个数,既比a[i]大,又比a[j]大
            }
        }
        printf("%lld\n", ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WTcrazy _

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值