题目链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
解法一:暴力遍历
第一个方法直接遍历所有矩形并以当前的矩形为起点向前倒回遍历并比较得到最小高度然后用最小高度乘以这一段范围,代码如下
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
int ans = 0;
int minH = 0;
int len = heights.size();
for(int i = 0; i < len; i++)
{
//剪枝一下第一个判断防止数组越界,如果前面矩形高度小于后一个高度直接跳过,因为后面高度大的矩形向前遍历时会访问前一个低矩形此范围会比从前一个高度低的矩形向前遍历的面积大
if( (i+1 <= len-1) && (heights[i] <= heights[i+1]) )
continue;
minH = heights[i];
for(int j = i; j >= 0; j--)
{
minH = min(minH, heights[j]);
ans = max(ans, minH*(i-j+1));
}
}
return ans;
}
};
此方法时间复杂度O(n^2)
解法二:单调栈
这个方法的关键就是维护一个递增的栈,放入的是高度对应的下标,遍历数组,如果栈为空直接放入当前高度对应的小标,不为空比较当前高度和栈顶元素对应的高度,如果栈顶元素小,则放入当前高度对应下标。否则出栈并计算出栈顶元素对应高度那片区域的面积,再重复比较当前数组高度和新的栈顶元素对应高度重复上述过程,代码如下
class Solution
{
public:
int largestRectangleArea(vector<int>& heights)
{
stack<int>s;
heights.push_back(0); //leetcode会卡数据,最后的数据是[1]
int len = heights.size();
int ans = 0;
int minH = 0; //最小高度
for(int i = 0; i < len; i++)
{
if( s.empty() || heights[i]>=heights[s.top()] )
s.push(i);
else
{
minH = heights[s.top()];
s.pop();
int temp = s.empty() ? minH*i : minH*(i-s.top()-1);//栈代表矩形高度递增,栈为空时说明最后的栈顶元素对应高度是最小的
ans = max(ans, temp);
i--;
}
}
return ans;
}
};