LeetCode:85. 最大矩形

题目链接

85. 最大矩形

题目描述

给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例:

输入:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
输出: 6

解题思路

第一步

我们把矩形横向定义为长,纵向定义为宽。

计算出每一点向右画,最远能画到多少。

换句话说,我们求出每一点宽为1的时候,长最大是多少。

例如对于样例中的输入,我们的计算结果是

1 0 1 0 0 
1 0 3 2 1 
5 4 3 2 1 
1 0 0 1 0 

再给一个样例

{{'1','1','1','1','1','1','1','1'},
{'1','1','1','1','1','1','1','0'},
{'1','1','1','1','1','1','1','0'},
{'1','1','1','1','1','0','0','0'},
{'0','1','1','1','1','0','0','0'}}

对于这个样例,我们的计算结果是

8 7 6 5 4 3 2 1 
7 6 5 4 3 2 1 0 
7 6 5 4 3 2 1 0 
5 4 3 2 1 0 0 0 
0 4 3 2 1 0 0 0 

第二步

根据第一步计算结果计算最大矩形。

这里面有一个木桶原理,木桶能装多少水,取决于木桶的最短板。

对于每一个点,我们只考虑向右和向下的方向。第一步计算出了向右方向——最大的长。

接下来,我们开始向下扩展,每向下扩展一行,宽就要+1,长就会变成扩展的k行里面的最小值,面积就要动态变化,这样就可以找到每个点的面积最大值。

最后再找到全局最大值。

解题代码

class Solution {

    public int maximalRectangle(char[][] matrix) {
		int m = matrix.length;
		
		if (m == 0) {
			return 0;
		}
		int n = matrix[0].length;

		int[][] l = new int[m][n];

		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				if (matrix[i][j] == '0') {
					l[i][j] = 0;
					continue;
				}
				int index = j + 1;
				while (index < n && matrix[i][index] == '1') {
					index++;
				}
				l[i][j] = index - j;
			}

		}

		int maxS = 0;
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				//遍历每个点,以该点为左上角
				
				if (l[i][j] == 0) {
					continue;
				}
				
				int s = l[i][j];
				for (int k = 1; k < m - i && matrix[i + k][j] != '0'; k++) {
					
					int minL = l[i][j];
					// 找到 由i到i+k的最小值
					for (int t = i + 1; t <= i + k; t++) {
						if (minL >= l[t][j]) {
							minL = l[t][j];
						}
					}
					//当前点为左上角,面积所能达到的最大值
					s = Math.max((k + 1) * minL, s);
				}

				maxS = Math.max(maxS, s);

			}
		}
		return maxS;
	}

}

测试代码

public static void main(String[] args) {

		Solution s = new Solution();
		char[][] b = { { '1', '0', '1', '0', '0' }, 
				{ '1', '0', '1', '1', '1' },
				{ '1', '1', '1', '1', '1' },
				{ '1', '0', '0', '1', '0' } };
		char[][] b1 = { { '1', '1', '1', '1', '1', '1', '1', '1' },
				{ '1', '1', '1', '1', '1', '1', '1', '0' },
				{ '1', '1', '1', '1', '1', '1', '1', '0' }, 
				{ '1', '1', '1', '1', '1', '0', '0', '0' },
				{ '0', '1', '1', '1', '1', '0', '0', '0' } };
		System.out.println(s.maximalRectangle(b1));
		System.out.println(s.maximalRectangle(b));
	}

 测试结果:

21

6

解题结果

66 / 66 个通过测试用例

状态:

通过

执行用时:42 ms

你可能感兴趣的:(百练OJ与leetcode)