题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
思路
- 暴力遍历,果然超时了
- 分治法:先找到最短的一个柱子,则结果应当为以下三个面积的最大值:
a. 以最短柱子为高,长为柱子数目
b. 最短柱左侧最大面积
c. 最短柱右侧最大面积
然而需要注意的是如果柱子是有序的,分治法与暴力法没有区别,也会超时,因此需要判断柱子是否有序,若有序,则从左向右挨个计算右侧面积;若无序,则分治 - 栈的用法:主要思想在于遍历数组,找到以数组中每个元素为高度所能得到的最大面积,利用单调栈,具体可以自行画图来理解或参考
代码
方法一:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if(heights.size()==0)
return 0;
int length = heights.size();
int maxarea = 0;
for(int i = 0;i<length;i++)
{
int min_height = heights[i];
for(int t = i;t>=0;t--)
{
min_height = min(min_height,heights[t]);
maxarea = max(maxarea,min_height*(i-t+1));
}
}
return maxarea;
}
};
方法二:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if(heights.size()==0)
return 0;
int length = heights.size();
return Help(heights,0,length-1);
}
int Help(vector<int>& heights,int start, int end)
{
if(start > end)
return 0;
int mid = start;
bool sorted = true;
for (int i = start+1; i <= end; ++i) {
if(heights[i]<heights[i-1])
sorted=false;
if(heights[i] < heights[mid]){
mid=i;
}
}
if(sorted)
{
int mx=0;
for(int i=start;i<=end;++i)
mx = max(mx,(end-i+1)*heights[i]);
return mx;
}
else
return max(heights[mid]*(end-start+1),max(Help(heights,start,mid-1),Help(heights,mid+1,end)));
}
};
方法三:
class Solution {
public:
int largestRectangleArea(vector<int>& heights)
{
int ans = 0;
vector<int> st;
heights.insert(heights.begin(), 0);
heights.push_back(0);
for (int i = 0; i < heights.size(); i++)
{
while (!st.empty() && heights[st.back()] > heights[i])
{
int cur = st.back();
st.pop_back();
int left = st.back() + 1;
int right = i - 1;
ans = max(ans, (right - left + 1) * heights[cur]);
}
st.push_back(i);
}
return ans;
}
};