84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10
知道思路跟42.接雨水差不多,但是还是不懂得变通,没写出来。
双指针法:
先记录每一个柱子的左边第一个低于该柱子的坐标和右边第一个低于该柱子的坐标。
通过坐标差值和当前柱子高度计算出矩形面积。
值得注意的是,在记录左边/右边第一个小于当前柱子高度的柱子坐标minleft[i]时,可以通过寻找前一个柱子,如果小于直接赋值,如果大于则可通过前一个的minleft循环直到找到目标值,这也是对比暴力法求值所减少的重复计算。
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
vector<int> minleft(heights.size(),0);
vector<int> minright(heights.size(),0);
minleft[0]=-1;
for(int i=1;i<heights.size();i++){
int t=i-1;
//通过循环找到第一个小于当前柱子高度的坐标!!!!(与暴力法不同)
while(t>=0&&heights[t]>=heights[i]) t=minleft[t];
minleft[i]=t;
}
minright[heights.size()-1]=heights.size();
for(int i=heights.size()-2;i>=0;i--){
int t=i+1;
while(t<heights.size()&&heights[t]>=heights[i]) t=minright[t];
minright[i]=t;
}
int result=0;
for(int i=0;i<heights.size();i++){
int h=heights[i];
int w=minright[i]-minleft[i]-1;
result=max(result,h*w);
}
return result;
}
};
单调栈法:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int result=0;
stack<int> st;
heights.insert(heights.begin(),0);
heights.push_back(0);
st.push(0);
for(int i=1;i<heights.size();i++){
if(heights[i]>heights[st.top()]){
st.push(i);
}
else if(heights[i]==heights[st.top()]){
st.pop();
st.push(i);
}
else{
while(!st.empty()&&heights[i]<heights[st.top()]){
int mid=st.top();
st.pop();
if(!st.empty()){
int w=i-st.top()-1;
int h=heights[mid];
result=max(result,h*w);
}
}
st.push(i);
}
}
return result;
}
};