[230527 lc84] 柱状图中最大的矩形
一 题目
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ziV92sDJ-1685179820700)(null)]
输入: heights = [2,4]
输出: 4
提示:
-
1 <= heights.length <=105
-
0 <= heights[i] <= 104
二 整体思路
一道很典型的单调栈的题目。思路是利用单调栈找到每一个高度左边的第一个较小高度和右边的第一个较小高度,记录其下标,根据下标计算出对应高度所能达到的最大宽度,计算其面积。最后选取最大值返回。
三 关键点/重点/难点
对于单调栈来说,理解到找较小元素应该使用递增单调栈、找较大元素应该使用递减单调栈即可。找当前元素右边的第一个元素,使用正序遍历;找当前元素左边的第一个元素,使用倒序遍历。
这道题还有一个需要注意的点,在两个数组的初始化。左边元素数组应该初始化为 -1,右边元素数组应该初始化为 size。
四 代码分析
class Solution {
public:
//应该是要找到,左边第一个小于自身的高度和右边第一个小于自身的高度
//维护非严格递增单调栈:从栈底到栈顶是单调递增的
int largestRectangleArea(vector<int>& heights) {
stack<int> stk;
vector<int> firstLeft(heights.size(), -1);
vector<int> firstRight(heights.size(), heights.size());
//正序遍历,构造firstRight
for(int i = 0; i < heights.size(); ++i) {
while(!stk.empty() && heights[stk.top()] > heights[i]) {
int index = stk.top();
stk.pop();
firstRight[index] = i;
}
stk.push(i);
}
while(!stk.empty()) {
stk.pop();
}
//倒序遍历,构造minRight
for(int i = heights.size() - 1; i >= 0; --i) {
while(!stk.empty() && heights[stk.top()] > heights[i]) {
int index = stk.top();
stk.pop();
firstLeft[index] = i;
}
stk.push(i);
}
int result = 0;
for(int i = 0; i < heights.size(); ++i) {
int tmp = heights[i] * (firstRight[i] - firstLeft[i] - 1);
result = max(tmp, result);
}
return result;
}
};
(五)一题多解
单调栈太典型了,不想写了。
(六) 知识扩展
相关题目:
85. 最大矩形:求出以矩阵的每一行为底对应的柱状图,然后求每一个柱状图中的最大矩形面积,从中取最大值。