[LeetCode]85. 最大矩形(java实现)单调栈
1. 题目
2. 读题(需要重点注意的东西)
思路:
基于[LeetCode]84. 柱状图中最大的矩形(java实现)单调栈,我们可以求出在一个柱状图中,矩形的最大面积;
将其扩展为二维,对于本题中的矩阵,以每一行 i 为底,我们都可以看作一个独立的[LeetCode]84. 柱状图中最大的矩形问题,如下图:
则本题转换为不同高度下的[LeetCode]84. 柱状图中最大的矩形问题,求出每个高度下的最大矩形,取max即可。
3. 解法
---------------------------------------------------解法---------------------------------------------------
class Solution {
public int maximalRectangle(char[][] matrix) {
if(matrix.length == 0) return 0;
int n = matrix.length,m = matrix[0].length;
int[][] h = new int[n][m];
// 初始化以每行为底的h数组
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++)
// 注意数组matrix中是char,不是int
if(matrix[i][j] != '0')
if(i > 0) h[i][j] = h[i-1][j] + 1;
// 初始化第0行
else h[i][j] = 1;
int res = 0;
for(int i = 0;i < n;i++) res = Math.max(res,largestRectangleArea(h[i]));
return res;
}
public int largestRectangleArea(int[] h) {
int n = h.length;
int[] left = new int[n + 10];
int[] right = new int[n + 10];
// 定义一个单调栈,用数组实现
int[] stk = new int[n + 10];
// 单调栈索引
int tt = 0;
// 从左往右扫描每个矩形左边的第一个比它小的数的下标
for(int i = 0;i < n;i++){
while(tt != 0 && h[stk[tt]] >= h[i]) tt--;
if(tt == 0) left[i] = -1;
else left[i] = stk[tt];
stk[++tt] = i;
}
// 从右往左扫描每个矩形右边的第一个比它小的数的下标
// 索引归0
tt = 0;
for(int i = n - 1;i >= 0;i--){
while(tt != 0 && h[stk[tt]] >= h[i]) tt--;
if(tt == 0) right[i] = n;
else right[i] = stk[tt];
stk[++tt] = i;
}
// 扫描一遍数组,求出答案
int res = 0;
for(int i = 0;i < n;i++) res = Math.max(res,(right[i] - left[i] - 1) * h[i]);
return res;
}
}
可能存在的问题: