zoukankan      html  css  js  c++  java
  • 单调栈

    久闻单调栈,亦使用之,然使用频率过低,常遗忘。今重温,记录在册,往能常记之。

    什么是单调栈

    单调栈就是栈里面存放的数据都是有序的,所以可以分为单调递增栈和单调递减栈两种。

    1. 单调递增栈就是从栈底到栈顶是从大到小
    2. 单调递减栈就是从栈底到栈顶是从小到大

    应用:

    1.视野总和

    描叙:有n个人站队,所有的人全部向右看,个子高的可以看到个子低的发型,给出每个人的身高,问所有人能看到其他人发型总和是多少。
    输入:10 3 7 4  12
    输出:4

    分析:对于每一个元素a[i]找到右边第一个大于他的元素a[j],则j-i-1即为a[i]能看到的人的数目

    比如:a[1]=10,右边第一个大于他的元素为a[5]=12,则第1个人能看到5-1-1=3个人

    a[2]=3,右边第一个大于他的元素为a[3]=7,则第2个人能看到3-2-1=0个人

    a[3]=7,右边第一个大于他的元素为a[5]=12,则第3个人能看到5-3-1=1个人

    a[4]=4,右边第一个大于他的元素为a[5]=12,则第4个人能看到4-3-1=0个人

    单调递减栈:

    初始,栈空

    1:10入栈;

    2:3<10,入栈后能保持栈的递减,则3入栈

    3:7>栈顶元素3,入栈后不能保持栈的递减,则3出栈。同时说明7是第2个人右边第一个比他高的人,则其能看到的人为3-2-1

    4:4<7,入栈后能保持栈的递减,则4入栈

    5:12>栈顶元素4,入栈后不能保持栈的递减,则4出栈。4出栈后,12依然>栈顶元素7,入栈后不能保持栈的递减,则7出栈,说明身高7和4的人右边第一个比他们高的人是12,此时可以计算出这两人能看到的人数。

    由该样例可以看出:每个元素被踢出栈时,将他踢出栈的人,则是他右边第一个比他高的人。

    深思还可以发现,每个元素在栈中时,紧邻他的左边那个元素也是他左边第一个比他高的人。

    总结:单调递减栈可以得出左右都比他高的第一人是谁。

    2.给出一个矩形统计图,它的每个矩形的宽度都为1,高度是题目所给。要你求出这个矩形图中最大面积的长方形。

    矩形统计图的数据为 [4, 3, 2, 5, 6]

    分析:以每一个柱形图的高度为高h,统计其左边最大可达位置,与其右边最大可达位置

    即统计其左边第一个比他小的元素下标x(左边界),与右边第一个比他小的元素下标y(右边界)。 

    则该位置高度为h的矩形面积为h*(y-x-1)、

    由此可以使用递增单调栈来完成

    初始,栈空

    1:4入栈(其左边没有元素,默认左边界为0)

    2:3<4不满足递增性质,4出栈,3入栈,3的左边界同4(0);则高度为4的矩形面积为4*(2-0-1)=4;

    3:2<3不满足递增性质,3出栈,2入栈,2的左边界同3(0);则高度为3的矩形面积为3*(3-0-1)=6;

    4:5>2满足递增性质,5入栈,其左边界为栈中左边元素的下标3

    5:6>5满足递增性质,6入栈,其左边界为栈中左边元素的下标4

    所有元素入栈完毕,此时栈不空,则栈中元素依次出栈,同时计算以其高度为标准的矩形面积

    第一步6 出栈,其右边界为6,左边界为4,则s=(6-4-1)*6=6

    第二步5 出栈,其右边界同上一个出栈元素,也为6,左边界为3,则s=(6-3-1)*5=10

    第三步2 出栈,其右边界同上一个出栈元素,也为6,左边界为0,则s=(6-0-1)*2=10

    3.给定一个整型矩阵map,其中的值只有0和1两种,求其中全是1的所有矩形区域中,最大的矩形区域为1的数量。
    例如:
    1 1 1 0
    其中,最大的矩形区域有3个1,所以返回3。
    再如:
    1 0 1 1
    1 1 1 1
    1 1 1 0
    其中,最大的矩形区域有6个1,所以返回6.

    分析:

    这是一个二维数组,不好直接完成,我们可以尝试压缩成一维数组来完成

    具体如下:以每行为参照标准,计算该行上面每列1的个数,然后使用单调递增栈,这样就求出了每行为基准含有1的个数

    该行上面每列1的个数,统计方法:

    以第i行,第j列为例:

      if(a[i][j]==1) s[i][j]=s[i-1][j]+1;//为上一行该位置1的个数+1,a[i][j]原矩阵,s[i][j]统计第i行第j列其上面有多少个连续出现的1.

      else s[i][j]=0;//如果a[i][j]==0则该位置1的个数是0个,不关心其上面有多少1

    题目来源:

    https://zhuanlan.zhihu.com/p/101785785

    https://blog.csdn.net/lucky52529/article/details/89155694

    单调栈:P1901,p1950,P1565

  • 相关阅读:
    nullnullConnecting with WiFi Direct 与WiFi直接连接
    nullnullUsing WiFi Direct for Service Discovery 直接使用WiFi服务发现
    nullnullSetting Up the Loader 设置装载机
    nullnullDefining and Launching the Query 定义和启动查询
    nullnullHandling the Results 处理结果
    装置输出喷泉装置(贪心问题)
    数据状态什么是事务?
    停止方法iOS CGD 任务开始与结束
    盘文件云存储——金山快盘
    函数标识符解决jQuery与其他库冲突的方法
  • 原文地址:https://www.cnblogs.com/ssfzmfy/p/14812365.html
Copyright © 2011-2022 走看看