1.问题思路
如何找到最大矩形?找到比上一个元素高度低的索引位置,不断进行计算构成矩形的面积,取最大值。
这里由于找的是第一个低的位置,所以这里使用单调递减栈(栈顶元素最大,栈底元素最小)。
边缘两端也需要进行计算面积,可以声明一个新的数组,左右边界高度为0。遍历数组时,对于元素可分为如下三种情况进行讨论。
- heights[i] > heights[stack.peek()],进行入栈, 维护单调递减栈
- heights[i] = heights[stack.peek()],这里入栈与否其实不影响计算结果。
- heights[i] < heights[stack.peek()],heights[stack.peek()]代表中间元素,也是最大的元素。那么如何找到中间元素的左端最高的元素呢?其实左端最高元素在栈中的第二个位置。循环判断stack不为空,进行计算面积即可。
2.代码实现
class Solution {
int maxArea = 0;
public int largestRectangleArea(int[] heights) {
// 两端需要计算
int[] newHeight = new int[heights.length+2];
for(int index = 0; index < heights.length; index++) {
newHeight[index+1] = heights[index];
}
heights = newHeight;
// 单调递减栈
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
for(int i=1; i<heights.length; i++) {
// 当前遍历元素大于栈顶元素,需进行入栈
if (heights[i] > heights[stack.peek()]) {
stack.push(i);
}
// 等于的话,这里其实入不入栈意义不大
else if(heights[i] == heights[stack.peek()]) {
stack.push(i);
}
// 遇到比当前小的元素,意味着中间元素在栈顶, 是最大的,需要进一步计算左右端高度,进而计算面积
else {
while(heights[i] < heights[stack.peek()]) {
// 中间最大高度, 需要找到中间两边较小的元素作为高。遍历计算最大面积
int midIndex = stack.pop();
if (!stack.isEmpty()) {
int leftIndex = stack.peek();
int height = heights[midIndex];
int width = i - leftIndex - 1;
maxArea = Math.max(width * height, maxArea);
}
}
stack.push(i);
}
}
return maxArea;
}
}
本文解析了如何使用单调递减栈解决LeetCode题目84,通过比较当前元素与栈顶元素高度,找出最大矩形的边界,计算并更新最大面积。
996

被折叠的 条评论
为什么被折叠?



