单调栈

参考博客:
https://blog.csdn.net/hebtu666/article/details/82717317
单调栈性质:

1、若是单调递增栈,则从栈顶到栈底的元素是严格递增的。若是单调递减栈,则从栈顶到栈底的元素是严格递减的。

2、越靠近栈顶的元素越后进栈。(显而易见)

用法一
给出一个柱形统计图(histogram), 它的每个项目的宽度是1, 高度和具体问题有关。 现在编程求出在这个柱形图中的最大面积的长方形。

7 2 1 4 5 1 3 3

7表示柱形图有7个数据,分别是 2 1 4 5 1 3 3, 对应的柱形图如下,最后求出来的面积最大的图如右图所示。
在这里插入图片描述
维护一个单调递增栈,所有元素各进栈和出栈一次即可。每个元素出栈的时候更新最大的矩形面积。

当前元素小于栈顶,就可以更新栈顶元素的最大长度了,并且把栈顶弹出,弹出后栈顶还是大,那就继续更新,继续弹出,知道当前元素能放进去。

栈顶下面一个元素一定是它左边第一个比栈顶小的元素,当前元素一定是右边第一个比栈顶小的元素。

用法二 找出矩形数量
假设给你一组数代表矩形的高度,而矩形的宽度为一,问你这样的图形包含多少个矩形。矩形的形状可以相同,但是矩形的位置不能相同

方法----单调栈

  • 定义数组 L[ ] :代表左边界 R [ ] :代表右边界 H[ ] : 代表柱体的高度 S [ ] :模拟单调栈 top 栈顶
  • 正向扫描 确定柱体的左边界 把零入栈 ,对于高度H【 i】遍历,如果高度比栈顶元素高入栈 否则把大于等于它的元素出栈 它入栈 每次用L【】 记录下标
  • 逆向扫描 确定右边界
  • 那么矩形数量 (i-L[i])*(R[i]-i)*H[i] 的累加

比较着代码更容易理解

int calc(int *h)
{
    //正向扫描
    s[top=0]=0;
    for(int i=1;i<=n;i++)
    {
        while(top&&h[i]<=h[s[top]]) --top;
        l[i]=s[top];s[++top]=i;
    }

     /*for(int i=1;i<=n;i++)
     {
         cout<<l[i]<<" ";
     }
     cout<<endl;*/
	//逆向扫描
    s[top=0]=n+1;
    for(int i=n;i>=1;i--)
    {
        while(top&&h[i]<h[s[top]]) --top;
        r[i]=s[top];
        s[++top]=i;
    }

   /* for(int i=1;i<=n;i++)
    {
        cout<<r[i]<<" ";
    }
    cout<<endl;*/
	//矩形数量累加
    int res=0;
    for(int i=1;i<=n;i++)
    {
        res=(res+(i-l[i])*(r[i]-i)*h[i]%mod)%mod;
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值