给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
一:暴力破解
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) {
return 0;
}
//保存以当前数字结尾的连续 1 的个数
int[][] width = new int[matrix.length][matrix[0].length];
int maxArea = 0;
//遍历每一行
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
//更新 width
if (matrix[row][col] == '1') {
if (col == 0) {
width[row][col] = 1;
} else {
width[row][col] = width[row][col - 1] + 1;
}
} else {
width[row][col] = 0;
}
//记录所有行中最小的数
int minWidth = width[row][col];
//向上扩展行
for (int up_row = row; up_row >= 0; up_row--) {
int height = row - up_row + 1;
//找最小的数作为矩阵的宽
minWidth = Math.min(minWidth, width[up_row][col]);
//更新面积
maxArea = Math.max(maxArea, height * minWidth);
}
}
}
return maxArea;
}
柱状图矩阵的方法
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) {
return 0;
}
int[] heights = new int[matrix[0].length];
int maxArea = 0;
for (int row = 0; row < matrix.length; row++) {
//遍历每一列,更新高度
for (int col = 0; col < matrix[0].length; col++) {
if (matrix[row][col] == '1') {
heights[col] += 1;
} else {
heights[col] = 0;
}
}
//调用上一题柱状图矩阵的解法,更新函数
maxArea = Math.max(maxArea, largestRectangleArea(heights));
}
return maxArea;
}
public int largestRectangleArea(int[] heights) {
int[] leftLessMin = new int[heights.length];
leftLessMin[0] = -1;
for (int i = 1; i < heights.length; i++) {
int l = i - 1;
while (l >= 0 && heights[l] >= heights[i]) {
l = leftLessMin[l];
}
leftLessMin[i] = l;
}
int[] rightLessMin = new int[heights.length];
rightLessMin[heights.length - 1] = heights.length;
for (int i = heights.length - 2; i >= 0; i--) {
int r = i + 1;
while (r <= heights.length - 1 && heights[r] >= heights[i]) {
r = rightLessMin[r];
}
rightLessMin[i] = r;
}
int maxArea = 0;
for (int i = 0; i < heights.length; i++) {
int area = (rightLessMin[i] - leftLessMin[i] - 1) * heights[i];
maxArea = Math.max(area, maxArea);
}
return maxArea;
}