题面
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
e.g.
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10
思路
最开始的时候确实不知道这道题和单调栈有什么关系,但是也是积极尝试了。试了一下用单调栈排了排这几个数,然后想了想推了推就出来了。很开心第一次独立手搓一道hard。
基本思路是这样的:
- 显然这个矩形的计算公式是:
,是针对一个区间而言的。
- 那么->对于每一个起始下标,应该能找到某种规律,找到一些面积的极大值。
- 区间之高等同于区间内的最矮柱,那么单调栈解决的问题应该是下一个更小柱->单调非增栈。
- 对于每一个起始下标,迭代的终止条件就是找到的终止下标右侧不再存在更小值。而此时的最大面积计算也会有所不同,因为右侧不再存在最小值意味着可以直接将从最右侧到起始下标的区间作为矩形宽。
这一通分析下来,基本思路就能定下来了。但是第一次编码还是显得很乱,也没跑通。
静下来整理了一下,用笔画一画前后双指针的移动更新、终止条件等等,就一下子编码、然后ac了。
class Solution {
public:
vector<int> getNextSmallerNum(vector<int>& heights){
vector<int> nextSmaller(heights.size(), -1);
stack<int> st;
st.push(0);
for(int i = 1; i < heights.size(); i++){
if(heights[i] >= heights[st.top()]) st.push(i);
else{
while(!st.empty() && heights[i] < heights[st.top()]){
nextSmaller[st.top()] = i;
st.pop();
}
st.push(i);
}
}
return nextSmaller;
}
int largestRectangleArea(vector<int>& heights) {
vector<int> nextSmaller = getNextSmallerNum(heights);
int max_area = 0;
for(int i = 0; i < heights.size(); i++){
int pre = i;
int post = nextSmaller[pre];
int cur_area = 0;
while(nextSmaller[pre] != -1){
cur_area = (post - i) * heights[pre];
max_area = max(max_area, cur_area);
pre = post;
post = nextSmaller[post];
}
cur_area = (heights.size() - i) * heights[pre];
max_area = max(max_area, cur_area);
}
return max_area;
}
};

被折叠的 条评论
为什么被折叠?



