题:https://leetcode.com/problems/maximal-rectangle/description/
题目
Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
Example:
Input:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
Output: 6
解法
DP思想,对于每个 i,j 求它的 左右边界和累加的高度然后算法矩形的面积,由于高度为可以累加的,左右边界是继承的,即,上个row的i,j 的边界和现在i,j的边界关系是上个row的边界一定包含当前row边界。
通过左右各次扫描能得出相应的边界。
可以和 [LeetCode] 79. Word Search 对比下
故从上个row中提取最好,可能成为当前row最好的,这就是题目中的状态转移。
https://leetcode.com/problems/maximal-rectangle/discuss/29054/Share-my-DP-solution
The DP solution proceeds row by row, starting from the first row. Let the maximal rectangle area at row i and column j be computed by [right(i,j) - left(i,j)]*height(i,j).
All the 3 variables left, right, and height can be determined by the information from previous row, and also information from the current row. So it can be regarded as a DP solution. The transition equations are:
left(i,j) = max(left(i-1,j), cur_left), cur_left can be determined from the current row
right(i,j) = min(right(i-1,j), cur_right), cur_right can be determined from the current row
height(i,j) = height(i-1,j) + 1, if matrix[i][j]==’1’;
height(i,j) = 0, if matrix[i][j]==’0’
The code is as below. The loops can be combined for speed but I separate them for more clarity of the algorithm.
code
class Solution:
def maximalRectangle(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
m = len(matrix)
if m == 0:
return 0
n = len(matrix[0])
bleft = {}
bright ={}
heights = {}
for i in range(n):
bleft[i] = -1
bright[i] = n
heights[i] = 0
maxm = 0
for i in range(m):
cur_left = -1
cur_right = n
for j in range(n):
if matrix[i][j] == "1":
bleft[j] = max(bleft[j],cur_left)
heights[j] += 1
else:
bleft[j] = -1
cur_left = j
heights[j] = 0
for j in range(n-1,0-1,-1):
if matrix[i][j] == "1":
bright[j] = min(bright[j],cur_right)
else:
bright[j] = n
cur_right = j
for j in range(n):
maxm = max(maxm,heights[j]*(bright[j]-bleft[j]-1))
return maxm