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
class Solution(object):
def maximalRectangle(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
if not matrix:
return 0
M = len(matrix)
N = len(matrix[0])
dp = [[0]*N for _ in range(M)]
maxarea = 0
for i in range(M):
for j in range(N):
if matrix[i][j] == '0':
continue
dp[i][j] = dp[i][j-1] + 1 if j else 1
width = dp[i][j]
for k in range(i,-1,-1):
width = min(width,dp[k][j])
maxarea = max(maxarea, width*(i-k+1))
return maxarea
时间复杂度:O(M^2N), M为matrix的行数,N为matrix的列数
空间复杂度:O(MN)
将matrix按照行转化成histogram,对每一行及以上的matrix形成的histogram利用leetcode 84的方法就可以了
class Solution(object):
def maximalRectangle(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
def helper(heights):
stack = []
maxarea = 0
heights.append(0)
n = len(heights)
for i in range(n):
if not stack or heights[i]>heights[stack[-1]]:
stack.append(i)
else:
while stack and heights[i]<=heights[stack[-1]]:
h = heights[stack[-1]]
stack.pop()
w = i if not stack else i-stack[-1]-1
maxarea = max(maxarea,h*w)
stack.append(i)
return maxarea
if not matrix:
return 0
maxarea = 0
dp = [0] * len(matrix[0])
for i in range(len(matrix)):
for j in range(len(matrix[0])):
dp[j] = dp[j] + 1 if matrix[i][j] == '1' else 0
maxarea = max(maxarea,helper(dp))
return maxarea
时间复杂度:O(M*N), M为matrix的行数,N为matrix的列数
空间复杂度:O(N)
class Solution(object):
def maximalRectangle(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
if not matrix:
return 0
m = len(matrix)
n = len(matrix[0])
left = [0]*n
right = [n]*n
height = [0]*n
maxarea = 0
for i in range(m):
curr_left = 0
curr_right = n
for j in range(n):
if matrix[i][j] == '1':
height[j] += 1
else:
height[j] = 0
for j in range(n):
if matrix[i][j] == '1':
left[j] = max(left[j],curr_left)
else:
left[j] = 0
curr_left = j+1
for j in range(n-1,-1,-1):
if matrix[i][j] == '1':
right[j] = min(right[j],curr_right)
else:
right[j] = n
curr_right = j
for j in range(n):
maxarea = max(maxarea, height[j]*(right[j]-left[j]))
return maxarea
时间复杂度:O(M*N), M为matrix的行数,N为matrix的列数
空间复杂度:O(N)
关于三种方法的详细解答,参见leetcode的官方解法