单调栈
一个单调递增(递减)的栈。在题目应用中主要是对栈的维护,通过判断和出入栈操作对栈进行维护,使之保持单调的状态。
维护
判断栈顶元素与数组元素的大小,如果 栈顶元素 < 数组元素 使栈顶元素出栈,如果 栈顶元素 > 数组元素 使数组元素入栈。
一个单调递减栈的例子:
进栈元素分别为3,4,2,6,4,5,2,3
3进栈:(3)
3出栈,4进栈:(4)
2进栈:(4,2)
2出栈,4出栈,6进栈:(6)
4进栈:(6,4)
4出栈,5进栈:(6,5)
2进栈:(6,5,2)
2出栈,3进栈:(6,5,3)
直方图是由在公共基线处对齐的一系列矩形组成的多边形。
矩形具有相等的宽度,但可以具有不同的高度。
例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1:
题目——直方图中的最大矩形
通常,直方图用于表示离散分布,例如,文本中字符的频率。
现在,请你计算在公共基线处对齐的直方图中最大矩形的面积。
图例右图显示了所描绘直方图的最大对齐矩形。
输入格式
输入包含几个测试用例。
每个测试用例占据一行,用以描述一个直方图,并以整数n开始,表示组成直方图的矩形数目。
然后跟随n个整数h1,…,hn。
这些数字以从左到右的顺序表示直方图的各个矩形的高度。
每个矩形的宽度为1。
同行数字用空格隔开。
当输入用例为n=0时,结束输入,且该用例不用考虑。
输出格式
对于每一个测试用例,输出一个整数,代表指定直方图中最大矩形的区域面积。
每个数据占一行。
请注意,此矩形必须在公共基线处对齐。
数据范围
1≤n≤100000,
0≤hi≤1000000000
输入样例:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
输出样例:
8
4000
初始化三个数组
int a[100010];
int stack[100010];//栈
int l[100010];//记录当前的长度
从第一个元素开始判断,如果数组元素大于栈顶元素就入栈,并把当前长度记录为1;
int j=0;
if(a[i]>stack[j])
{
stack[++j]=a[i];
l[j]=1;
}
如果没有达到入栈要求,就挨个出栈,直到再次满足入栈要求。每出栈一次就计算一次面积,并进行判断,保留最大值。
int ans=0;//初始化
int len=0;
long long int S;
while(stack[j]>a[i])
{
len+=l[j];
S=(long long int)len*stack[j];//因为len和stack[]都是int,但结果会爆int
if(S>ans)//判断大小,保留最大面积
ans=S;
j--;//出栈操作
}
出栈完之后达到入栈要求(单调递增),将数组元素入栈,并记录len,方便下次使用。
stack[++j]=a[i];//达到入栈要求,将数组元素入栈
l[j]=len+1;//记录长度
最后就输出结果就可以了。