84.柱状图中最大的矩形 ★
文档讲解 : 代码随想录 - 84.柱状图中最大的矩形
状态:再次回顾。(★:需要多次回顾并重点回顾)
和接雨水类似,本题建议和接雨水进行比较深化思路
思路:
在接雨水中接雨水的单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。
那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序。
栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度。
除此以外,还需要注意两点:
-
在
height
数组末尾加0
如果数组本身就是升序的,例如
[2,4,6,8]
,那么入栈之后都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0
了。 如图:
-
在
height
数组开头加0
如果数组本身是降序的,例如
[8,6,4,2]
,在8
入栈后,6
开始与8
进行比较,此时我们得到mid(8)
,right(6)
,但是得不到left
。因为 将
8
弹出之后,栈里没有元素了,那么为了避免空栈取值,直接跳过了计算结果的逻辑。之后又将
6
加入栈(此时8已经弹出了),然后 就是4
与栈口元素8
进行比较,周而复始,那么计算的最后结果result
就是0
。 如图所示:
本题代码:
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> st;
heights.insert(heights.begin(), 0); // 数组头部加入元素0
heights.push_back(0); // 数组尾部加入元素0
st.push(0);
int result = 0;
for (int i = 1; i < heights.size(); i++) {
while (heights[i] < heights[st.top()]) {
int mid = st.top();
st.pop();
int w = i - st.top() - 1;
int h = heights[mid];
result = max(result, w * h);
}
st.push(i);
}
return result;
}
};