题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10
知识点
单调栈
我的实现
结果
码前思考
我第一次写的时候知道这是一个单调栈的题目,但是,思考问题的角度错了:
我以为求最大矩形的长度是固定一个高度然后往右边扩散。。。。
后来提交错误了一次后发现,根据 木桶效应 ,应该是固定一个高度然后 向左和向右扩散 ,所以按照原则来说要用两次单调栈,第一次用于寻找右边第一个小于当前元素的元素。第二次用于寻找左边第一个小于当前元素的元素。
代码实现
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
//定义一个单调栈,是递减栈
stack<int> st;
int maxArea = 0;
int len = heights.size();
vector<int> left(len);
vector<int> right(len);
//然后从右到左开始进行单调栈的操作
for(int i=len-1;i>=0;i--){
int h = heights[i];
while(!st.empty() && heights[st.top()]>=h){
st.pop();
}
if(st.empty()){
right[i] = len;
}else{
right[i] = st.top();
}
st.push(i);
}
//然后再是另一边
//然后从右到左开始进行单调栈的操作
while(!st.empty()){
st.pop();
}
for(int i=0;i<len;i++){
int h = heights[i];
while(!st.empty() && heights[st.top()]>=h){
st.pop();
}
if(st.empty()){
left[i] = -1;
//maxArea = max(maxArea,h*(i+1));
}else{
left[i] = st.top();
}
st.push(i);
}
for(int i=0;i<len;i++){
maxArea = max(maxArea,(right[i]-left[i]-1)*heights[i]);
}
return maxArea;
}
};
码后反思
- 其实我的代码非常的冗杂,但是这样我更好理解一些,官方题解太精简了,不适合我这种菜鸟;
- 以后看到寻找左右第一个大于小于的元素就要想到用单调栈。如果是右边第一个大于,则是递增栈,如果是第一个小于,则是递减栈。左边同理,只是遍历的方向不一样。