原題如下:
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;
}