题目
https://leetcode.com/problems/maximal-rectangle/
题解
本题与 leetcode 84. Largest Rectangle in Histogram | 84. 柱状图中最大的矩形(单调栈) 思路相同,直接抄了原来的代码。
也可参考之前的博客:左神算法:求最大子矩阵的大小(Java版)
另外,想到了另外一道类似但思路不同的题:221. Maximal Square
class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) return 0;
int M = matrix.length;
int N = matrix[0].length;
int[][] heights = new int[M][N]; // 上方有多少个连续的1
for (int i = 0; i < N; i++) {
heights[0][i] = matrix[0][i] - '0';
for (int j = 1; j < M; j++) {
if (matrix[j][i] == '1') heights[j][i] = heights[j - 1][i] + 1;
else heights[j][i] = 0;
}
}
int result = 0;
for (int i = 0; i < M; i++) {
result = Math.max(largestRectangleArea(heights[i]), result);
}
return result;
}
// leetcode 84. Largest Rectangle in Histogram
public int largestRectangleArea(int[] heights) {
int L = heights.length;
// 找左边第一个小于h[i]的数
// 从右向左遍历,维护单调不减栈,小数h[i]不断将大数h[j]弹出,则h[i]左边第一个小于h[i]的数为h[j]
Stack<Integer> valueStack = new Stack<>();
Stack<Integer> indexStack = new Stack<>();
int[] leftIndex = new int[L]; // i左边第一个小于i的数的下标
Arrays.fill(leftIndex, -1);
for (int i = L - 1; i >= 0; i--) {
while (!valueStack.isEmpty() && valueStack.peek() > heights[i]) {
leftIndex[indexStack.pop()] = i;
valueStack.pop();
}
valueStack.push(heights[i]);
indexStack.push(i);
}
// 找右边第一个小于h[i]的数
// 从左向右遍历,维护单调不减栈
valueStack = new Stack<>();
indexStack = new Stack<>();
int[] rightIndex = new int[L]; // i右边第一个小于i的数的下标
Arrays.fill(rightIndex, L);
for (int i = 0; i < L; i++) {
while (!valueStack.isEmpty() && valueStack.peek() > heights[i]) {
rightIndex[indexStack.pop()] = i;
valueStack.pop();
}
valueStack.push(heights[i]);
indexStack.push(i);
}
// 对于每个h[i],以其自身的高度,分别向左右扩张
int maxArea = 0;
for (int i = 0; i < L; i++) {
maxArea = Math.max(maxArea, (rightIndex[i] - leftIndex[i] - 1) * heights[i]);
}
return maxArea;
}
}