-
2.24
- with 想到了,但是面积放错了,放在 while 的外面了
-
2.14
- 备份一个尾部为 0 的数组,用于对比 length-1 的位置
- 单调栈永远是递增的,弹出时会永久弹出
- 宽度为 i-stack。peek()-1,因为 i 的位置是左边目前最高位置的下标,因为 while 循环,peek 会一直弹出到低于当前位置高度的前一个位置
-
2.2
- 先备份新的,然后看栈顶(位置)来记录高和宽,尝试更新
- 不管怎样都 push 当前位置
-
2.1
- 维护一个单调栈,当,当前的高度小于单调栈栈顶的元素时,弹出栈顶元素作为高,然后根据情况找宽度,尝试更新面积
import java.util.ArrayDeque;
import java.util.Deque;
class Solution {
public int largestRectangleArea(int[] heights) {
// 1. 新建一个数组,长度比原数组大 1 (或者大 2,头尾各加一个 0)
// 这里采用只在末尾加 0 的写法,比较通用
int n = heights.length;
int[] newHeights = new int[n + 1];
// 拷贝原数组,newHeights 最后一位默认为 0
for (int i = 0; i < n; i++) {
newHeights[i] = heights[i];
}
// 2. 单调栈 (存下标)
Deque<Integer> stack = new ArrayDeque<>();
int maxArea = 0;
for (int i = 0; i < newHeights.length; i++) {
// 当当前高度 < 栈顶高度时,说明找到了栈顶元素的“右边界”
// 必须是 while,因为当前元素可能比栈里好几个元素都矮
while (!stack.isEmpty() && newHeights[stack.peek()] > newHeights[i]) {
// 1. 弹出栈顶,作为高 (H)
int curHeight = newHeights[stack.pop()];
// 2. 获取对应的宽 (W)
// 右边界是 i (当前元素的下标)
// 左边界是栈顶元素 (弹出 cur 后剩下的栈顶)
int curWidth;
if (stack.isEmpty()) {
curWidth = i; // 如果栈空了,说明 curHeight 是目前最矮的,一直延伸到 0
} else {
curWidth = i - stack.peek() - 1; // 标准公式:右 - 左 - 1
}
// 3. 更新面积
maxArea = Math.max(maxArea, curHeight * curWidth);
}
// 保持单调递增,入栈
stack.push(i);
}
return maxArea;
}
}