原题如下:
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
.
int largestRectangleArea(vector<int> &height) {
int len = height.size();
if(len == 0 )
return 0;
if(len == 1)
return height[0];
vector<int>min(len,0);
int maxArea = 0;
for(int i = 0; i < len; i++){ //依次遍历数组元素i,计算i与其后节点j之间的最大面积
if(height[i] * (len - i) <= maxArea) // 如果以height[i]为高度计算其后整个的面积都小于maxArea,那么以i为起点的可以略过
continue;
for(int j = i; j < len; j++ ){
if(j == i)
min[j] = height[i];
else if(height[j] < min[j - 1])
min[j] = height[j];
else
min[j] = min[j - 1];
if(j != len - 1 && height[j] < height[j + 1])
continue;
if(min[j] * (j - i + 1) > maxArea)
maxArea = min[j] *(j - i + 1);
}
}
return maxArea;
}
另外还有一种改进的方法,在这篇博文中对改进的方法进行了详细的介绍:
http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html,这种方法的大体思路如下:首先在原数组的末尾添加元素0作为结束符(其作用在算法中体现),另外需要一个栈来保存递增高度的下标,在遍历原数组的过程中,当栈为空或栈中元素下标所在的元素值的高度小于当前遍历的下标的高度,则将当前遍历的下标入栈,否则,计算当前栈中栈顶元素与比当前元素值大的下标之间的最大面积,这里需要注意的是以栈中为下标的元素值是递增的,所以在依次出栈计算时其高度是不断减小的,该高度所表示的范围是其栈中前一个节点之后的范围,所以在计算其宽度时是i - 1 (i - 1为栈顶元素下标)减去其下一个元素的下标,所以需要在获得高度值int t = s.top();之后先出栈以获得宽度(其栈中下一个元素)再计算面积,所以需要对栈为空时进行特殊处理,而且需要注意栈中元素下标值是不连续的。还是借助上述博客中的图比较容易理解,另外需要注意在上述博客中有一个图存在一些小错误。
int largestRectangleArea(vector<int> &height) {
int len = height.size();
if(len == 0)
return 0;
if(len == 1)
return height[0];
stack<int>s; //保存之前的下标
int maxArea = 0;
height.push_back(0);
len++;
int i = 0;
while(i < len){
if(s.empty() || height[s.top()] <= height[i])
s.push(i++);
else{
int t = s.top();
s.pop();
maxArea = max(maxArea,height[t] *(s.empty()?i:(i - 1 - s.top())));
}
}
return maxArea;
}