标签:
单调栈是栈中的元素从栈顶到栈底单调递增或递减。单调栈只能从栈顶部添加或者删除元素,以单调递增栈为例,元素从栈顶到栈底逐渐递增,假设当前元素为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