给定非负整数数组 heights
,数组中的数字用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1
。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
int[] left = new int[n];
int[] right = new int[n];
Deque<Integer> mono_stack = new ArrayDeque<Integer>();
for (int i = 0; i < n; ++i) {
while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
mono_stack.pop();
}
left[i] = (mono_stack.isEmpty() ? -1 : mono_stack.peek());
mono_stack.push(i);
}
mono_stack.clear();
for (int i = n - 1; i >= 0; --i) {
while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
mono_stack.pop();
}
right[i] = (mono_stack.isEmpty() ? n : mono_stack.peek());
mono_stack.push(i);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
}
return ans;
}
}
//答案源于力扣官方题解
使用一个单调栈 mono_stack
来找到 left
和 right
的值。首先,遍历 heights
,对于每个元素,如果栈不为空且栈顶元素对应的柱子高度大于等于当前柱子高度,那么就将栈顶元素弹出,因为当前柱子会遮挡住它,使得它无法成为其他柱子的左侧第一个比它矮的柱子。然后,将当前柱子的下标压入栈中。这样,栈中的元素对应的柱子高度是单调递减的。
生成了左右两个数组
left[i] 存储的是 heights[i] 左侧第一个比它矮的柱子的下标,如果不存在,则设为 -1
right[i] 存储的是 heights[i] 右侧第一个比它矮的柱子的下标,如果不存在,则设为 n 是 heights 的长度
因为数组最后是向两边进行扩张的,所以这两个数组可以确定下这个目标柱子外左右的界限,然后进入最后一个for循环算出来答案