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 heights = [2,1,5,6,2,3]
,
return 10
.
使用单调栈来来求解。其中一个单调栈来记录元素,另一个非单调记录栈来同步记录这个元素之前相连的连续大于其值的元素的记录值和并加1。
遍历数组,当元素入栈符合单调栈的特性时,则元素入栈,记录栈插入元素1。当元素入栈后破坏单调栈的特性时,不断弹出栈内元素,直到元素入栈后依然符合单调栈的特性,同时同步更新记录栈,新元素的记录值等于弹出元素的记录值的和并加1.
代码如下:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> monotony;
stack<int> count;
int max = 0;
for(int i = 0;i < heights.size();i++)
{
if(monotony.empty() || heights[i] >= monotony.top())
{
monotony.push(heights[i]);
count.push(1);
}
else if(heights[i] < monotony.top())
{
int num = 0;
while(!monotony.empty() && monotony.top() > heights[i])
{
if(max < (count.top()+num)*monotony.top())
max = (count.top()+num)*monotony.top();
monotony.pop();
num += count.top();
count.pop();
}
monotony.push(heights[i]);
count.push(num+1);
}
}
int num = 0;
while(!monotony.empty())
{
if(max < (count.top()+num)*monotony.top())
max = (count.top()+num)*monotony.top();
monotony.pop();
num += count.top();
count.pop();
}
return max;
}
};
觉得自己的代码依然写的像坨shit - - 如何改进,如何更优雅,依然是个大问题。参考别人的代码进行优化如下:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0);
int size = heights.size();
if(size==1)
return 0;
stack<int> stk;
int result = 0;
for(int i=0;i<size;)
{
if(stk.empty() || heights[i]>heights[stk.top()])
{ stk.push(i);
i++;
continue;
}
int h = heights[stk.top()];
stk.pop();
int left = stk.empty()? -1 : stk.top();
result = max(result,(i-left-1)*h);
}
return result;
}