2021.03.25柱状图中最大矩形
( 题目来源:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/ )
题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
思路
思路1:暴力
依次遍历每一个高度对应的矩形,求出最大值。
思路1 代码
public int largestRectangleArea(int[] heights) {
int n = heights.length;
if(n == 0) return 0;
for(int i = 0; i < n; i++) {
int curH = heights[i];
int left = i, right = i;
//向左
while(left > 0 && heights[left-1] >= curH)
left--;
//向右
while(right < n-1 && heights[right+1] >= curH)
right++;
ans = Math.max(ans, (right-left+1)*curH);
}
return ans;
}
思路2:单调栈
public int largestRectangleArea2(int[] heights) {
int n = heights.length;
int[] left = new int[n];
int[] right = new int[n];
//左边界数组,记录的左边界的下标
Stack<Integer> mono_stack = new Stack<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;
}