问题描述:
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]
.
The largest rectangle is shown in the shaded area, which has area = 10
unit.
Example:
Input: [2,1,5,6,2,3] Output: 10
题目意思就是给定一个数组,数组中存着各个位置的高度,让求出最大矩形的面积
解题思路:
最初的想法是暴力解决,遍历到一个位置i的时候,以i为矩形的左边,找到矩阵的面积,若大于当前矩形面积,则替换。这样做虽然可以通过,但是时间复杂度太高,面试官也无法满足,于是就考虑用一种增量栈的方法。
增量栈,顾名思义就是保持栈中元素是增量的。步骤如下:
- 若栈为空或者栈顶索引对应的元素比当前索引对应的元素小,则将当前元素的索引入栈;
- 若栈不为空且栈顶索引对应的元素比当前索引对应的元素大,则一次出栈,直到栈顶索引对应的元素比当前索引对应的元素小。出栈的时候计算以栈顶索引对应的元素为高度的矩形面积,因为栈中索引对应的元素是递增的,所以矩形的宽度由当前元素的索引减去栈顶索引即可;
- 遍历结束后若栈仍不为空,则一次弹出,并计算面积。
注意:
- (入栈出栈都是索引,为了方便计算宽度)
- 留意栈为空的情况,栈中的最后一个索引对应的元素比之前遍历的所有元素都小,此时直接用当前遍历的索引代替宽度。比如2,3,4,1。遍历到元素1(索引3)的时候会一直出栈到空,则以2为高度的矩形宽度直接用3.
样例为2 1 5 6 2 3
i=0:栈为0
i=1:栈输出0,result更新,输入1
i=2:栈为1 2
i=3:栈为1 2 3
i=4:栈依次输出3 2,并动态更新result,输入4
i=5:栈为1 4 5
栈依次输出5 4 1,并动态更新result
Tips:更新result是指比较原有result,与i的左边第一条的边作为矩形右边的边,栈顶的右边的第一条边作为矩形左边,而围城的矩形的面积(有点拗口,理解一下),当然要是此时栈为空,左边的边的序号就以0算。
代码:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> h;
int result = 0;
for(int i=0; i<heights.size(); i++){
if(h.empty() || heights[i]>=heights[h.top()]){
h.push(i);
}
else{
while(!h.empty() && heights[i]<heights[h.top()]){
int tmp = heights[h.top()];
h.pop();
int tmpw = h.empty()?i:i-h.top()-1;
result = max(result, tmp*tmpw);
}
h.push(i);
}
}
while(!h.empty()){
int tmp = heights[h.top()];
h.pop();
int tmpw = h.empty()?heights.size():heights.size()-h.top()-1;
// cout<<tmp<<" "<<tmpw<<endl;
result = max(result, tmp*tmpw);
}
return result;
}
};