leetCode85.最大矩形

版权声明:前半生,不害怕;后半生,不后悔! https://blog.csdn.net/qq_14842117/article/details/89226161

给定填充0和1的2D二进制矩阵,找到仅包含1的最大矩形并返回其区域。
Example:
Input:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
Output: 6

这题有点儿像leetcode中求直方图的最大矩形的区域(见下方链接),不过这题是二维的,还要考虑高度,可以一行一行的处理。
最大矩形区域

本题需要3个辅助数组,
left(i,j) 表示当前行的有‘1’的左侧最大列。
right(i,j)表示当前行的有‘1’的右侧最小列。
height(i,j)表示当前位置相对于第一层的高度

如果您认为此算法不易理解,可以尝试以下示例:
0 0 0 1 0 0 0 
0 0 1 1 1 0 0 
0 1 1 1 1 1 0
从第0行到第2行的向量“左”和“右”如下
row 0:

l: 0 0 0 3 0 0 0
r: 7 7 7 4 7 7 7
row 1:

l: 0 0 2 3 2 0 0
r: 7 7 5 4 5 7 7 
row 2:

l: 0 1 2 3 2 1 0
r: 7 6 5 4 5 6 7
left数组计算左边界。以matrix(1,3)为例。在当前行1上,左边界位于j=2.但是,因为矩阵matrix[1][3]1,你也需要考虑之前行该列,left数组取所有行当前列的最大值。所以(1,3)处的实际左边界是3.
public int maximalRectangle(char [][] matrix) {
	  if(matrix.length == 0) return 0;
	  int m = matrix.length;
	  int n = matrix[0].length;
	 int [] left = new int[n];
	 int [] right = new int[n];
	  Arrays.fill(right,n);
	  int [] height = new int[n];
	  int maxA = 0;
	  for(int i = 0;i<m;i++) {
		  int cur_left = 0,cur_right = n;
		  for(int j = 0;j<n;j++) {//计算高度(可以从任何一侧开始)
			if(matrix[i][j] == '1') height[j]++;
			else height[j] = 0;
		  }
		  for(int j = 0;j<n;j++) {//计算左边界(从左到右)
			  if(matrix[i][j] =='1') left[j] = Math.max(left[j],cur_left);
			  else {left[j] = 0;cur_left =j+1;}
	      }
		  for(int j = n-1;j>=0;j--) {//计算右边界(从右到左)
			if(matrix[i][j] =='1') right[j] = Math.min(right[j], cur_right);
			else {right[j] = n;cur_right = j;}
		  }
		  for(int j = 0;j<n;j++) {//计算矩形区域(可以从另一边)
			maxA = Math.max(maxA,(right[j]-left[j])*height[j]);
		  }
   }
   return maxA;
}

猜你喜欢

转载自blog.csdn.net/qq_14842117/article/details/89226161
今日推荐