Problem
Given a rows x cols binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
Algorithm
Dynamic Programming (DP). The same problem as Leetcode 84.
We decompose the problem into the largest rectangle, that is, solve the largest rectangle in the graph whose bottom side is k, and then merge to find the largest rectangle.
Preprocessing: Calculate the maximum continuous 1 height MaxH from the bottom of each row of the bottom of each row.
O
(
N
2
)
O(N^2)
O(N2)
DP: For the bottom side of each layer, we use a monotonic queue to find the largest rectangle of the row.
O
(
N
)
O(N)
O(N)
For the solution analysis of monotonic queue, please refer to the solution of Leetcode 84.
Overall time cost:
T
(
N
)
=
O
(
N
2
)
+
O
(
N
)
∗
O
(
N
)
=
O
(
N
2
)
T(N) = O(N^2)+O(N)*O(N) = O(N^2)
T(N)=O(N2)+O(N)∗O(N)=O(N2).
Code
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
if not matrix:
return 0
rows = len(matrix)
cols = len(matrix[0])
Maps = [[0] * (cols + 2) for i in range(rows + 2)]
for i in range(rows):
for j in range(cols):
Maps[i+1][j+1] = matrix[i][j]
MaxH = Maps.copy()
for i in range(rows):
for j in range(cols):
if Maps[i+1][j+1] == '1':
MaxH[i+1][j+1] = MaxH[i][j+1] + 1
else:
MaxH[i+1][j+1] = 0
for i in range(rows):
MaxH[i+1][0] = MaxH[i+1][cols+1] = -1
MaxV = 0
MUQ = [0] * (cols + 2)
L = [0] * (cols + 2)
R = [0] * (cols + 2)
for i in range(1, rows+1, 1):
tail = 0
MUQ[0] = 0
for j in range (1, cols+2, 1):
while tail >= 0 and MaxH[i][MUQ[tail]] > MaxH[i][j]:
R[MUQ[tail]] = j
tail -= 1
tail += 1
MUQ[tail] = j
tail = 0
MUQ[0] = cols+1
for j in range(cols, -1, -1):
while tail >= 0 and MaxH[i][MUQ[tail]] > MaxH[i][j]:
L[MUQ[tail]] = j
tail -= 1
tail += 1
MUQ[tail] = j
for j in range(1, cols+1, 1):
Temp = MaxH[i][j] * (R[j] - L[j] - 1)
if MaxV < Temp:
MaxV = Temp
return MaxV