携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
题目
给定一个仅包含 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
示例 3
输入:matrix = [["0"]]
输出:0
示例 4
输入:matrix = [["1"]]
输出:1
示例 5
输入:matrix = [["0","0"]]
输出:0
提示
- rows == matrix.length
- cols == matrix[0].length
- 1 <= row, cols <= 200
- matrix[i][j] 为 '0' 或 '1'
题解
思路
- 当前坐标产生最大矩形的算法
- 减枝
第一个问题:
(1)遍历横坐标找到当前纵坐标的 1 的长度 cnx (2)纵坐标 +1 以后再开始遍历横坐标 cnx,得出最小 cnx,cnXmin (3)当前面积就是:纵坐标*cnXmin
注:搜索到 0 就停止
第二个问题:
计算当前坐标可能出现的最大矩形的 value,如果这个 value 小于当前存储的结果值,则不需要遍历
代码
class Solution {
public:
int res = 0;
void getMaxRect(vector<vector<char>>& matrix,int y,int x){
int ny = matrix.size();
int nx = matrix[0].size();
if(matrix[y][x] == '0')
return;
int cny = 0;
int cnx = 0;
int cnXmin = INT_MAX;
for(int j=y;j<ny;j++){
for(int i=x;i<nx;i++){
if(matrix[j][i] == '1'){
cnx++;
}else{
break;
}
}
if(cnx == 0)
break;
cnXmin = min(cnXmin,cnx);
cny++;
res = max(res,cnXmin*cny);
cnx = 0;
}
}
int maximalRectangle(vector<vector<char>>& matrix) {
int ny = matrix.size();
int nx = matrix[0].size();
for(int y=0;y<ny;y++){
for(int x=0;x<nx;x++){
if(matrix[y][x] == '1') {
int mayMax = (ny-y)*(nx-x);
if(res > mayMax)
continue;
// 开始寻找最大矩形
getMaxRect(matrix,y,x);
}
}
}
return res;
}
};
结语
业精于勤,荒于嬉;行成于思,毁于随。