题目描述:
给你一个二进制矩阵 matrix ,它的大小为 m x n ,你可以将 matrix 中的 列 按任意顺序重新排列。
请你返回最优方案下将 matrix 重新排列后,全是 1 的子矩阵面积。
示例 1:
输入:matrix = [[0,0,1],[1,1,1],[1,0,1]] 输出:4 解释:你可以按照上图方式重新排列矩阵的每一列。 最大的全 1 子矩阵是上图中加粗的部分,面积为 4 。 |
示例 2:
输入:matrix = [[1,0,1,0,1]] 输出:3 解释:你可以按照上图方式重新排列矩阵的每一列。 最大的全 1 子矩阵是上图中加粗的部分,面积为 3 。 |
示例 3:
输入:matrix = [[1,1,0],[1,0,1]] |
提示:
- m == matrix.length
- n == matrix[i].length
- 1 <= m * n <= 105
- matrix[i][j] 要么是 0 ,要么是 1 。
题目分析:
提前对数据做预处理:遍历marix中每个点,计算竖直方向以该点为结尾的1的最大高度,也就是说,计算每个点上面有多少个连续的1,
这样处理之后,不用再单独计算在某个横切区间内某列上有多少个连续的1。
在数据预处理之后,便得到了每个点上方有多少个连续的1
,然后遍历每行,计算以该行为底的最大矩形面积,这就很简单了:
已经知道了每个点上方有多少个连续的1 |
以示例1为例:
代码:
public int largestSubmatrix(int[][] matrix) {
int length = matrix[0].length;
// 计算每一行,垂直方向上,到当前行为止连续的1的个数
for(int i=1; i<matrix.length; i++){
for(int j=0; j<length; j++){
if(matrix[i][j] == 1){
matrix[i][j] += matrix[i-1][j];
}
}
}
int result = 0;
for(int i=0; i<matrix.length; i++){
Arrays.sort(matrix[i]); //升序排列, 最后的高度是最大的
for(int j=length-1; j>=0; j--){
if(matrix[i][j] > 0){
// 计算面积,数组已升序排列,以当前高度为高,当前索引(j)到数组的长度(length) 为宽
result = Math.max(result, matrix[i][j]*(length - j));
}
}
}
return result;
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-submatrix-with-rearrangements