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
.
方法一:动态规划,这个思路其实是计算不同长度组合的面积,记录最大的。O(N^2)复杂度,小例子能过,大例子超时。
class Solution {
public:
int largestRectangleArea(vector<int> &height) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int n = height.size();
if(n == 0) return 0;
vector<int> minHeight(n,0);
int maxArea = 0;
for(int i = 0;i < n;i++)
{
minHeight[i] = height[i];
if(height[i] > maxArea) maxArea = height[i];
}
for(int l = 2;l <=n ;l++)
{
for(int j = n-1;j >= l-1;j--)
{
minHeight[j] = min(minHeight[j-1],height[j]);
int area = minHeight[j]*l;
if(area > maxArea) maxArea = area;
}
}
return maxArea;
}
};
方法二:
A more straight-forward and easy-to-learn method, no stack:
left[i] is the most-left side column that i can extend to;
left[i] = max{j: h[j]>h[i] && j<i};
right[i] is the most-right side column that i can reach at;
right[i] = min{j: h[j]>h[i] && j>i};
so, left[i] can be calculated recursively:
left[i+1] = left[i], if h[i+1] == h[i];
= i, if h[i+1] > h[i];
= 0~left[i], if h[i+1] < h[i]; this can be done recursively
such as right[i].
the rectangle area is calculated as: area[i] = (right[i]-left[i]-1) * h[i];
方法三:目前想到的复杂度最小的方法,为O(n)。思路是每次计算以当前height为限制的最大范围的面积,实际和方法二一样。
代码如下:
class Solution {
public:
int largestRectangleArea(vector<int> &height) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int size = height.size();
if( size == 0) return 0;
stack<int> stack;
int maxArea = 0;
for(int i = 0;i< size;i++)
{
while(!stack.empty() && height[stack.top()] > height[i]){
int top = stack.top();
stack.pop();
int last = (stack.empty())?0:stack.top()+1;
if(maxArea < height[top]*(i-last)) maxArea = height[top]*(i-last);
}
stack.push(i);
}
while(!stack.empty()){
int top = stack.top();
stack.pop();
int last = (stack.empty())?0:stack.top()+1;
int area = height[top]*(size-last);
if(maxArea <area ) maxArea = area;
}
return maxArea;
}
};
100 milli secs.
看到了更简洁的代码表达:
class Solution {
public:
int largestRectangleArea(vector<int> &h) {
stack<int> p;
int i = 0, m = 0;
h.push_back(0);
while(i < h.size()) {
if(p.empty() || h[p.top()] <= h[i])
p.push(i++);
else {
int t = p.top();
p.pop();
m = max(m, h[t] * (p.empty() ? i : i - p.top() - 1 ));
}
}
return m;
}
};
100 milli secs.