最大矩形
题目描述
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
输入样例
[ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ]
输出样例
6
解题思路
这道题涉及一个经典的问题:求矩阵的最大子矩阵,是典型的动态规划问题。
扫描二维码关注公众号,回复:
52020 查看本文章
首先应该看如何简化求解的过程,这道题的主要思路就是:对于矩阵中的每一个点,他的最大面积即是最大高度乘以该高度下延伸的最大宽度(其实这样对于每个矩阵的点的最大面积并不一定是对的,但是要这样子想,即使这一个点上的最大面积并不是在最大高度下延伸的宽度的面积。但是在同一行中,如果满足上述条件,必定有高度没有这么高的点,那在这些点里面,必定有一点可以求得刚才的面积存在,所以可以求出刚才那一个点的最大面积,最后的结果因而是正确的)
掌握了基本原理之后我们可以下递归原理:
首先最大高度很好理解,如果该点为0,那么该点的最大高度为0,如果非0,即为上一行最大高度加1,即
max_height[j] = max_height[j] + 1
其次是左/右端点,我们只需要找一个变量记录本行该点的左/右边界即可,但是还要满足在最大高度下的最大延伸,所以还要取上一行该点边界的较大/小值。故若该点为0,重置边界值,重设该点的左/右边界,否则,取上述值。
while j >= 0: if matrix[i][j] == "1": max_right[j] = min(max_right[j], right_border) else: right_border = j - 1 max_right[j] = n - 1 j = j - 1
接下来就比较简单了,求出最大面积即可。
代码展示
class Solution: def maximalRectangle(self, matrix): """ :type matrix: List[List[str]] :rtype: int """ m = len(matrix) n = 0 if m > 0: n = len(matrix[0]) max_height = [0 for i in range(0, n)] max_right = [n - 1 for i in range(0, n)] max_left = [0 for i in range(0, n)] max_area = 0 for i in range(0, m): left_border = 0 right_border = n - 1 for j in range(0, n): if matrix[i][j] == "1": max_height[j] = max_height[j] + 1 max_left[j] = max(max_left[j], left_border) else: max_height[j] = 0 left_border = j + 1 max_left[j] = 0 j = n - 1 while j >= 0: if matrix[i][j] == "1": max_right[j] = min(max_right[j], right_border) else: right_border = j - 1 max_right[j] = n - 1 j = j - 1 for j in range(0, n): if (max_right[j] - max_left[j] + 1) * max_height[j] > max_area: max_area = (max_right[j] - max_left[j] + 1) * max_height[j] return max_area