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.
For example,
Given height = [2,1,5,6,2,3]
,
return 10
.
这道题思路其实很清楚,就是拿用两个数组left,right, 来记录自己左边第一个比自己小的和右边第一个比自己小的坐标。具体的实现由递增栈来实现。每次的问题都出现在,如何存储正确形式的坐标上。由于height的idx是相当于一个长方形的高度,而不是具体的一个点的idx。所以在计算的时候,需要小心地考虑正确的坐标形式…说来说去说的太乱了,画个图简单来说,对于一个简单的例子,height = {2,1,5} 来说,坐标系我是这么选取的,
所以,对于height[0]来说,他的边界应该分别为-1(最靠左)和0(右边最小的idx-1). 同理,对于height[1]来说,他的边界应该分别为0(左边idx)和1(右边idx-1)。按照这样的顺序,在插入边界的时候对height[idx]的idx做出轻微修改,可以让所有的面积都用统一的表达式,(right-left)*height来表达。具体代码如下:
class Solution {
public:
int largestRectangleArea(vector<int>& height) {
stack<int> st;
vector<int> left(height.size());
for (int i = 0; i < height.size(); i++) {
while (!st.empty() && height[st.top()] >= height[i]) {
st.pop();
}
if (st.empty()) {
st.push(i);
left[i] = -1;
} else {
left[i] = st.top();
st.push(i);
}
}
vector<int> right(height.size());
while(!st.empty())
st.pop();
for (int i = height.size()-1; i >= 0; i--) {
while (!st.empty() && height[st.top()] >= height[i]) {
st.pop();
}
if (st.empty()) {
st.push(i);
right[i] = height.size()-1;
} else {
right[i] = st.top()-1;
st.push(i);
}
}
int result = 0;
for (int i = 0; i < height.size(); i++) {
result = max(result,(right[i]-left[i])*height[i]);
}
return result;
}
};