法1:单调栈[原版]
O(N)+O(N)
低保算法,必须掌握算法!!!
Python
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
res, n = 0, len(heights)
leftMin = [-1] * n
rightMin = [n] * n
stack = [] # 保存索引
for i in range(n): # 找左侧第1个 < heights[i]的索引
cur = heights[i]
while stack and heights[stack[-1]] >= cur:
stack.pop()
leftMin[i] = stack[-1] if stack else -1
stack.append(i)
stack = []
for i in range(n-1, -1, -1): # 找右侧第1个 < heights[i]的索引
cur = heights[i]
while stack and heights[stack[-1]] >= cur:
stack.pop()
rightMin[i] = stack[-1] if stack else n
stack.append(i)
for i in range(n):
res = max(res, (rightMin[i] - leftMin[i] - 1) * heights[i])
return res
Java
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length, res = 0;
int[] leftMin = new int[n], rightMin = new int[n];
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; ++i) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
stack.pop();
}
leftMin[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
stack.clear();
for (int i = n - 1; i >= 0; --i) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
stack.pop();
}
rightMin[i] = stack.isEmpty() ? n : stack.peek();
stack.push(i);
}
for (int i = 0; i < n; ++i) {
res = Math.max(res, (rightMin[i] - leftMin[i] - 1) * heights[i]);
}
return res;
}
}
法2:单调栈[优化版]
O(N)+O(N)
参考答案

class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length, res = 0;
int[] leftMin = new int[n], rightMin = new int[n];
Arrays.fill(rightMin, n); // 一定注意这次需要初始化!!!
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; ++i) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
rightMin[stack.peek()] = i;
stack.pop();
}
leftMin[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
for (int i = 0; i < n; ++i) {
res = Math.max(res, (rightMin[i] - leftMin[i] - 1) * heights[i]);
}
return res;
}
}
文章介绍了两种利用单调栈解决最大矩形面积问题的方法,分别是原版和优化版,时间复杂度均为O(N)。重点讲解了如何使用栈来维护每个高度的左右边界,以找到最大的矩形面积。
7717

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



