最大矩形
难度:
标签:
题目描述
给定一个仅包含 0
和 1
、大小为 rows x cols
的二维二进制矩阵,找出只包含 1
的最大矩形,并返回其面积。
示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 输出:6 解释:最大矩形如上图所示。
示例 2:
输入:matrix = [["0"]] 输出:0
示例 3:
输入:matrix = [["1"]] 输出:1
提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j]
为'0'
或'1'
代码结果
运行时间: 74 ms, 内存: 22.3 MB
/*
* 思路:
* 1. 与普通的Java实现相似,只是在遍历数组和栈操作上使用Stream API。
* 2. 使用Stream API将矩阵转换为高度数组,再计算每行的最大矩形面积。
*/
import java.util.Arrays;
import java.util.Stack;
public class MaximalRectangleStream {
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) return 0;
int[] heights = new int[matrix[0].length];
return Arrays.stream(matrix)
.mapToInt(row -> {
IntStream.range(0, row.length).forEach(j -> {
heights[j] = (row[j] == '1') ? heights[j] + 1 : 0;
});
return largestRectangleArea(heights);
})
.max()
.orElse(0);
}
private int largestRectangleArea(int[] heights) {
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
int index = 0;
while (index < heights.length) {
if (stack.isEmpty() || heights[index] >= heights[stack.peek()]) {
stack.push(index);
index++;
} else {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? index : index - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
}
while (!stack.isEmpty()) {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? index : index - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
return maxArea;
}
}
解释
方法:
这个题解采用了单调栈的方法。主要思路是:逐行遍历矩阵,并维护一个高度数组 heights,heights[j] 表示第 j 列当前的连续 1 的高度。对于每一行,利用单调栈求解以当前行作为矩形底边的最大矩形面积。具体做法是,遍历高度数组,对于每个高度,利用单调栈找到左右两侧第一个小于它的位置,计算以当前高度为矩形的高、左右位置的差值为矩形的宽,求出面积并更新全局最大面积。
时间复杂度:
O(m * n)
空间复杂度:
O(n)
代码细节讲解
🦆
在单调栈的应用中,如何确保每次计算矩形面积时,栈中存储的都是还未处理的高度的下标?
▷🦆
为什么在高度数组的首尾添加哨兵值0,这样的操作具体解决了哪些边界问题?
▷🦆
在遍历矩阵更新高度数组时,直接将遇到的'0'的高度重置为0,这种做法是否有可能忽略掉某些潜在的最大矩形?
▷🦆
函数`solve`中计算宽度为`i - k - 1`的原理是什么?这里的`i`和`k`分别指向哪些位置?
▷相关问题
柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4] 输出: 4
提示:
1 <= heights.length <=105
0 <= heights[i] <= 104
最大正方形
在一个由 '0'
和 '1'
组成的二维矩阵内,找到只包含 '1'
的最大正方形,并返回其面积。
示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 输出:4
示例 2:

输入:matrix = [["0","1"],["1","0"]] 输出:1
示例 3:
输入:matrix = [["0"]] 输出:0
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j]
为'0'
或'1'