题意:输入一个二维元素为0或1的矩阵,找到包含的1最多的矩形,返回该区域
思路:从左上角依次以1为矩形左上顶点,水平向右扩展直到遇到首个0位置,如果紧邻的元素是0,则直接放弃从该顶点开始的探索(一条边至少由两个元素组成),然后垂直向下搜索,原则类似水平向右搜索。同时,左上顶点的选择能跳过上一次选择过的的水平区域,即本次选择的左上顶点从0后面的首个1开始,而不用从1开始。<O(D^4),关键保持上一行的长度,因为下一行搜索的长度必须小于该长度
注意:矩阵是用字符数组,而非整形或者boolean数组
实现:暴力搜索法(72.05%), 测试时发现一个元素也能构成一个矩形,与我开始理解的矩形至少由长宽各2个元素的1组成。
public int maximalRectangle(char[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
return 0; //guard sentence
}
int maxArea = 0;
for(int row = 0; row < matrix.length; row++){
for(int col = 0; col < matrix[0].length; col++){ //左上顶点
:1
int localMaxArea = maxAreaFrom(row, col, matrix);
if(localMaxArea > maxArea){
maxArea = localMaxArea;
}
}
}
return maxArea;
}
//返回以左上顶点为起点的全1矩形的最大面积
private int maxAreaFrom(int row, int col, char[][] matrix) {
int localMaxArea = 0, area = 0;
int width = 0, lastLength = matrix[0].length - col;
for(int i = row; i < matrix.length; i++){
int length = 0;
for(int j = col; j < col + lastLength && j < matrix[0].length; j++){
if(matrix[i][j] == '0'){
break;
}
length++;
}
if(length == 0){
return localMaxArea;
}else{
width++;
area = width * length;
if(area > localMaxArea){
localMaxArea = area;
}
lastLength = length;
}
}
return localMaxArea;
}