题目描述
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4
提示:
1 <= heights.length <=105
0 <= heights[i] <= 104
解法
解法:暴力解法
java代码:
class Solution {
public int largestRectangleArea(int[] heights) {
if (heights.length == 0) {
return 0;
}
int res = 0;
for (int i = 0; i < heights.length; i++) {
if (heights[i] == 0) {
continue;
}
// 找左边大于等于当前值的位置,注意先比较前一个位置的值,再++,防止越界
int l = i;
while (l > 0 && heights[l - 1] >= heights[i]) {
l --;
}
// 找右边大于等于当前值的位置,注意先比较后一个位置的值,再++,防止越界
int r = i;
while (r < heights.length - 1 && heights[r + 1] >= heights[i]) {
r ++;
}
// 计算当前位置高度的最大矩形面积
int area = (r - l + 1) * heights[i];
res = Math.max(area, res);
}
return res;
}
}
复杂度
- 时间复杂度:
O(N^2)
N是输入数组的长度 - 空间复杂度:
O(1)
解法2:单调栈
java
class Solution {
public int largestRectangleArea(int[] heights) {
int len = heights.length;
if (len == 0) {
return 0;
}
if (len == 1) {
return heights[0];
}
int res = 0;
Deque<Integer> stack = new ArrayDeque<>();
// 第一遍循环,入栈,并把能计算出来的先计算了(就是当前元素小于栈顶元素了,栈顶元素是可以计算的了)
for (int i = 0; i < len; i++) {
// 这个 while 很关键,因为有可能不止一个柱形的最大宽度可以被计算出来
while (!stack.isEmpty() && heights[i] < heights[stack.peekLast()]) {
int curHeight = heights[stack.pollLast()];
while (!stack.isEmpty() && heights[stack.peekLast()] == curHeight) {
stack.pollLast();
}
int curWidth;
if (stack.isEmpty()) {
curWidth = i;
} else {
curWidth = i - stack.peekLast() - 1;
}
res = Math.max(res, curHeight * curWidth);
}
stack.addLast(i);
}
// 第二遍,栈不为空,继续弹栈
while (!stack.isEmpty()) {
int curHeight = heights[stack.pollLast()];
while (!stack.isEmpty() && heights[stack.peekLast()] == curHeight) {
stack.pollLast();
}
int curWidth;
if (stack.isEmpty()) {
curWidth = len;
} else {
curWidth = len - stack.peekLast() - 1;
}
res = Math.max(res, curHeight * curWidth);
}
return res;
}
}