标签:
单调栈是栈中的元素从栈顶到栈底单调递增或递减。单调栈只能从栈顶部添加或者删除元素,以单调递增栈为例,元素从栈顶到栈底逐渐递增,假设当前元素为e,在入栈时,从栈顶往下找,如果栈顶元素小于当前元素e,则弹出栈顶元素,直到栈顶元素小于等于该元素e,然后将e入栈;出栈时,直接弹出栈顶元素,即可得到栈中当前所有元素的最小值。
由于每个元素都会入栈和出栈一次,因此平摊下来,时间复杂度为O(n).
单调栈示例: poj 2559 Largest Rectangle in a Histogram
题目要求求出由给定的整数数组确定的直方图中,连续的一块最大的矩形面积,其中每个直方列的宽度均为1。
题目解法:
将关注点放在直方图的每个列上,由该列的高度确定的一个矩形(从该点的峰点出发,分别向左和向右延伸,得到最大的宽度,从而得到由该高度确定的矩形的面积)。然后进行一次遍历,得到所有点确定的矩形中最大的一个。
从一点向左(或右)延伸的最大长度(以向左延伸为例),就是从该点出发向左走,如果左边点的高度大于等于该点,则长度加1, 直到遇到的点的高度小于该点的高度则停止,得到最大值。这样的搜索过程,抽象出来,就是从一个序列尾部向前查找,找到合适的位置插入元素,从而形成一个递增的序列,然后从序列的尾部取出元素,这个过程可以用单调栈来实现。 在实现的时候,考虑求该点向左延伸时,左边最小的点的索引,并且将索引用栈来存储。
代码实现:注意 long long 的类型,以及 long long result = (right[i] - left[i] + 1)*hist[i]; (在hist 为整数数组时候,需要强制转换为 long long)
#include<stdio.h>
#include<stack>
#define MAX_NUM 100005
using namespace std;
int left[MAX_NUM];
int right[MAX_NUM];
int hist[MAX_NUM];
stack<int> index_stack;
void EmptyStack(stack<int> & stack){
while(! stack.empty()){
stack.pop();
}
}
long long GetLargestRect(int n){
EmptyStack(index_stack);
for(int i = 0; i < n; i ++){
while(! index_stack.empty() && hist[index_stack.top()] >= hist[i]){ //向左搜索,直到栈顶的元素小于当前元素
index_stack.pop();
}
left[i] = i;
if (! index_stack.empty()){
left[i] = index_stack.top() + 1; //得到最左的位置
}else{
left[i] = 0;
}
index_stack.push(i);
}
EmptyStack(index_stack);
for(int i = n - 1; i >= 0; i --){
while(! index_stack.empty() && hist[index_stack.top()] >= hist[i]){
index_stack.pop();
}
right[i] = i;
if (! index_stack.empty()){
right[i] = index_stack.top() - 1;
}else{
right[i] = n - 1;
}
index_stack.push(i);
}
long long max_area = 0;
for(int i = 0; i < n; i ++){
// printf("i = %d, left(i) = %d, right(i) = %d\n", i, left[i], right[i]);
long long result = (right[i] - left[i] + 1)*hist[i];
if (result > max_area){
max_area = result;
}
}
return max_area;
}
int main(){
while(true){
int n;
scanf("%d", &n);
if (n == 0){
break;
}
for(int i = 0; i < n; i ++){
scanf("%d", &hist[i]);
}
getchar();
long long result = GetLargestRect(n);
printf("%lld\n", result);
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/gtarcoder/p/4550269.html