Problem: 84. 柱状图中最大的矩形
题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
思路
因为题目所需要的是最大面积,则新加入的矮柱子对后面的面积计算很重要,在加入矮柱子后,该节点之前的高柱子全部失效。
所以我们需要一个单调增的栈来存放遍历节点之前的高柱子,当遍历到矮柱子时,对之前的所有高柱子进行清算,清算完成后将高柱子变成矮柱子,以维护单调增的栈性质。
例如当我们遍历到这个2时,需要对之前大于2的节点:5、6进行清算:
对于6节点,最大面积为6×1=6;
对于5节点,最大面积为5×2=10;
假设5前面还有4,则最大面积为4×3=12……
在对高柱子进行清算完毕后,为维护单调增的性质,需要将高柱子削平。
继续遍历下一个节点……
所以在遍历到最后一个节点时,栈中的情况如下:
此时我们发现,由于栈内没有更小的数字,无法促使栈进行清算行为,需要在函数的开始在最后加入“0”节点。
以此使得栈被动进行清算行为,对之前的节点进行遍历:
最大面积为3×1=3;
最大面积为2×2=4;
最大面积为2×3=6;
最大面积为2×4=8;
最大面积为1×5=5;
最大面积为1×6=6;
……
Code
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int result =heights[0];
stack<int> st;
heights.push_back(0);//加入最后的0高度
for(int i =0;i<heights.size();i++){
int j = 0;
while(!st.empty()&&heights[st.top()]>heights[i]){
result = max(result,(++j)*heights[st.top()]);//清算遍历
st.pop();
}
while(j--){
st.push(i-j);
heights[i-j]=heights[i];//强行降低高度
}
st.push(i);
}
return result;
}
};