84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]
。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10
个单位。
输入: [2,1,5,6,2,3]
输出: 10
方法一:暴力破解法
遍历到每一个柱子的左右,由这个柱子向两侧延申,直到遇到比其更小的h柱子,确定左右边界.对应的面积为w*h
public class LEE084L {
public int largestRectangleArea(int[] heights) {
int res = 0;
int n = heights.length;
for (int mid = 0; mid < n; mid++) {
int midHeight = heights[mid];
int a = mid;
int b = mid;
while (a - 1 >= 0 && heights[a - 1] >= midHeight) {
a--;
}
while (b + 1 < n && heights[b + 1] >= midHeight) {
b++;
}
res = Math.max(res, (b - a + 1) * midHeight);
}
return res;
}
}
方法二:单调栈
-
单调栈分为单调递增,单调递减
-
操作规则(下面都以单调递增栈为例)
如果新的元素比栈顶大,就入栈
如果新的元素比栈顶小,就弹出栈顶的元素,直到栈顶比新元素小.也就是新元素大
-
加入这样一个规则之后,会有什么效果
栈内的元素是递增的
当元素出栈时,说明这个新元素是出栈元素向后找第一个比其小的元素当元素出栈后,说明新栈顶元素是出栈元素向前找第一个比其小的元素
画图理解
思路
- 对于一个高度,如果能得到向左向右的边界
- 那么就能对每个高度求依次面积
- 遍历左所有高度,即可得出最大面积
- 使用单调栈,在出栈操作时得到前后边界并计算面积
public int largestRectangleArea(int[] heights) {
int res = 0;
ArrayDeque<Integer> stack = new ArrayDeque<>();
int[] newHeight = new int[heights.length + 2];
//给数组前后加零 , 以便数组后面完整的弹出栈中
for (int i = 1; i < heights.length + 1; i++) {
newHeight[i] = heights[i - 1];
}
for (int i = 0; i < newHeight.length; i++) {
//当栈为空,或者 当前栈顶的元素小于 后一个数组的元素
while (!stack.isEmpty() && newHeight[(int) stack.peek()] > newHeight[i]) {
//弹出栈顶的元素
int cur = stack.pop();
//前一个的元素位置
int l = stack.peek();
//后一个的位置
int r = i;
//计算大小
res = Math.max(res, (r - l - 1) * newHeight[cur]);
}
stack.push(i);
}
return res;
}
- 单调栈学习建议):「力扣」第 42、739、496、316、901、402、581 题。