-
Notifications
You must be signed in to change notification settings - Fork 43
/
maximal-rectangle.py
142 lines (103 loc) · 3.95 KB
/
maximal-rectangle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""
85. Maximal Rectangle
Hard
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.
Example 1:
Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.
Example 2:
Input: matrix = [["0"]]
Output: 0
Example 3:
Input: matrix = [["1"]]
Output: 1
Constraints:
rows == matrix.length
cols == matrix[i].length
1 <= row, cols <= 200
matrix[i][j] is '0' or '1'.
"""
# V0
# V1
# IDEA : BRUTE FOECE
# https://leetcode.com/problems/maximal-rectangle/solution/
# V1
# IDEA : Dynamic Programming - Better Brute Force on Histograms
# https://leetcode.com/problems/maximal-rectangle/solution/
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
maxarea = 0
dp = [[0] * len(matrix[0]) for _ in range(len(matrix))]
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == '0': continue
# compute the maximum width and update dp with it
width = dp[i][j] = dp[i][j-1] + 1 if j else 1
# compute the maximum area rectangle with a lower right corner at [i, j]
for k in range(i, -1, -1):
width = min(width, dp[k][j])
maxarea = max(maxarea, width * (i-k+1))
return maxarea
# V1
# IDEA : Using Histograms - Stack
# https://leetcode.com/problems/maximal-rectangle/solution/
class Solution:
# Get the maximum area in a histogram given its heights
def leetcode84(self, heights):
stack = [-1]
maxarea = 0
for i in range(len(heights)):
while stack[-1] != -1 and heights[stack[-1]] >= heights[i]:
maxarea = max(maxarea, heights[stack.pop()] * (i - stack[-1] - 1))
stack.append(i)
while stack[-1] != -1:
maxarea = max(maxarea, heights[stack.pop()] * (len(heights) - stack[-1] - 1))
return maxarea
def maximalRectangle(self, matrix: List[List[str]]) -> int:
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])):
# update the state of this row's histogram using the last row's histogram
# by keeping track of the number of consecutive ones
dp[j] = dp[j] + 1 if matrix[i][j] == '1' else 0
# update maxarea with the maximum area from this row's histogram
maxarea = max(maxarea, self.leetcode84(dp))
return maxarea
# V1
# IDEA : Dynamic Programming - Maximum Height at Each Point
# https://leetcode.com/problems/maximal-rectangle/solution/
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
if not matrix: return 0
m = len(matrix)
n = len(matrix[0])
left = [0] * n # initialize left as the leftmost boundary possible
right = [n] * n # initialize right as the rightmost boundary possible
height = [0] * n
maxarea = 0
for i in range(m):
cur_left, cur_right = 0, n
# update height
for j in range(n):
if matrix[i][j] == '1': height[j] += 1
else: height[j] = 0
# update left
for j in range(n):
if matrix[i][j] == '1': left[j] = max(left[j], cur_left)
else:
left[j] = 0
cur_left = j + 1
# update right
for j in range(n-1, -1, -1):
if matrix[i][j] == '1': right[j] = min(right[j], cur_right)
else:
right[j] = n
cur_right = j
# update the area
for j in range(n):
maxarea = max(maxarea, height[j] * (right[j] - left[j]))
return maxarea
# V2