给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]
。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10
个单位。
//暴力法
void dfs(int *heights,int heightsSize,int *ret)
{
if(heightsSize<=0)return;
int min=heights[0],min_pos=0;
for(int i=1;i<heightsSize;i++)
{
if(heights[i]<min)
{
min_pos=i;
min=heights[i];
}
}
int area=min*heightsSize;
*ret=*ret<area?area:*ret;
dfs(heights,min_pos,ret);
dfs(heights+min_pos+1,heightsSize-1-min_pos,ret);
}
int largestRectangleArea(int* heights, int heightsSize){
int ret=0;
dfs(heights,heightsSize,&ret);
return ret;
}
//单调递增栈法
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
//利用一个递增栈存储数组中的元素位置,当前位置高度小于栈顶元素对应高度时,栈顶元素出栈,直至当前位置元素可进栈
//当前需进栈元素的位置为面积计算终点
//栈顶元素出栈后,若栈为空,则当前位置前方所有位置大于栈顶元素
//-1为面积计算起点,
//若不为空,新的栈顶元素对应的位置为面积计算起点
//高等于出栈元素对应的高度
stack <int> increased_stack;
//末尾压入0是为了让前方所有元素出栈
heights.push_back(0);
int area=0;
for(int i=0;i<heights.size();i++)
{
while(!increased_stack.empty()&&heights[i]<heights[increased_stack.top()])
{
int top_tmp=increased_stack.top();
increased_stack.pop();
int start;
if(increased_stack.empty())start=-1;
else start=increased_stack.top();
area=area<(heights[top_tmp]*(i-start-1))?(heights[top_tmp]*(i-start-1)):area;
}
increased_stack.push(i);
}
return area;
}
};
示例:
输入: [2,1,5,6,2,3]
输出: 10
//暴力法
执行用时 : 1884 ms, 在Largest Rectangle in Histogram的C提交中击败了34.38% 的用户
内存消耗 : 9 MB, 在Largest Rectangle in Histogram的C提交中击败了18.52% 的用户
//单调栈法
执行用时 : 20 ms, 在Largest Rectangle in Histogram的C++提交中击败了87.30% 的用户
内存消耗 : 10.9 MB, 在Largest Rectangle in Histogram的C++提交中击败了6.30% 的用户