LC.P85[最大矩形]

方法一:二维转一维+单调栈

将矩阵的每一行看作是柱状图。

示例

[[“1”,”0”,”1”,”0”,”0”], 第一层,高度为[“1”,”0”,”1”,”0”,”0”]

[“1”,”0”,”1”,”1”,”1”], 第二层,高度为[“2”,”0”,”2”,”1”,”1”]

[“1”,”1”,”1”,”1”,”1”], 第三层,高度为[“3”,”1”,”3”,”2”,”2”]

[“1”,”0”,”0”,”1”,”0”]] 第四层,高度为[“4”,”0”,”0”,”3”,”0”]

求出每一层的最大面积可用LC.P84[柱状图中最大的矩形],并取其中的最大值即为答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0 || matrix[0].length == 0) return 0;
int row = matrix.length, col = matrix[0].length;
int[] heights = new int[col];
int ans = 0;
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
heights[j] = matrix[i][j] == '0' ? 0 : heights[j] + 1;
}
ans = Math.max(ans, largestRectangleArea(heights));
}
return ans;
}

// LC.P84[柱状图中最大的矩形]
public int largestRectangleArea(int[] heights) {
int n = heights.length, ans = 0;
int[] l = new int[n], r = new int[n];
Arrays.fill(l, -1);
Arrays.fill(r, n);
Deque<Integer> stack = new ArrayDeque<>();
// 确定右边界
for (int i = 0; i < n; ++i) {
while (!stack.isEmpty() && heights[stack.peek()] > heights[i]) r[stack.pop()] = i;
stack.push(i);
}
stack.clear();
// 确定左边界
for (int i = n - 1; i >= 0; --i) {
while (!stack.isEmpty() && heights[stack.peek()] > heights[i]) l[stack.pop()] = i;
stack.push(i);
}
for (int i = 0; i < n; ++i) {
int height = heights[i], width = r[i] - l[i] - 1;
ans = Math.max(ans, height * width);
}
return ans;
}
}
  • 时间复杂度:$O(mn)$
  • 空间复杂度:$O(mn)$