221. Maximal Square
思路:
This problem can be solved by dynamic programming. They key to DP is the state equation. In this problem, we define the state as the maximal size of the square that can be achieved at point (i, j)
, denoted as dp[i][j]
. Remember that we use size instead of square as the state (square = size * size
).
Now let's try to come up with the formula for dp[i][j]
.
First, it is obvious that for the topmost row (i = 0
) and the leftmost column (j = 0
), dp[i][j] = matrix[i][j]
. For example, if he topmost row of matrix
is [1, 0, 0, 1]
, we immediately know that the first and last point can be a square of size 1
while the two middle points cannot make any square, giving a size of 0
. Thus, dp = [1, 0, 0, 1]
, which is the same as matrix
. The case is similar for the leftmost column. Till now, the boundary conditions of this DP problem are solved.
Let's move to the more general case for dp[i][j]
in which i > 0
and j > 0
. First of all, let's see a simple sub-case in which matrix[i][j] = 0
. It is obvious that dp[i][j] = 0
since if matrix[i][j] = 0
, no square will contain matrix[i][j]
. According to our definition of dp[i][j]
, dp[i][j]
is also 0
.
Now we are almost done. The remaining sub-case is matrix[i][j] = 1
. Suppose matrix = [[0, 1], [1, 1]]
, it is obvious that dp[0][0] = 0, dp[0][1] = dp[1][0] = 1
, what about dp[1][1]
? Well, to give a square of size larger than 1
in dp[1][1]
, all of its three neighbors (left, upper, upper-left) should be non-zero. In this case, the upper-left neighbor dp[0][0] = 0
, so dp[1][1]
can only be 1, which means that the square only contains matrix[1][1]
. To summarize, dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
in this case.
The state equations are finally as follows.
dp[0][j] = matrix[0][j]
(topmost row);dp[i][0] = matrix[i][0]
(leftmost column);- For
i > 0
andj > 0
: ifmatrix[i][j] = 0
,dp[i][j] = 0
; ifmatrix[i][j] = 1
,dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
.
class Solution(object):
def maximalSquare(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
if not matrix:
return 0
row = len(matrix)
col = len(matrix[0])
size = [[0] * col for i in matrix]
res = 0
for i in xrange(row):
for j in xrange(col):
if col == 0:
size[i][j] = int(matrix[i][j])
else:
size[i][j] = min(size[i-1][j], size[i][j-1], size[i-1][j-1]) + 1 if int(matrix[i][j]) else 0
res = max(res, size[i][j])
return res*res
85. Maximal Rectangle
这题真难
DP:
class Solution(object):
def maximalRectangle(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
if not matrix or not matrix[0]: return 0
re, r, c = 0, len(matrix), len(matrix[0])
left = [0] * c # 1D from left to right, the index of leftmost continues 1
right = [c] * c # from right to left, the index of leftmost 1
height = [0] * c
for i in xrange(r):
# print i
curLeft, curRight = 0, c
for j in xrange(c): # compute height
if matrix[i][j] == '1':
height[j] += 1
else:
height[j] = 0
# print "heigh", height
for j in xrange(c):
if matrix[i][j] == '1': # compute left
left[j] = max(left[j], curLeft)
else:
left[j] = 0
curLeft = j+1
# print 'left-', left
for j in xrange(c-1, -1, -1): # right reverse of left
if matrix[i][j] == '1':
right[j] = min(right[j], curRight)
else:
right[j] = c # do not need to -1 otherwise right - left + 1 is the width
curRight = j
# print 'right', right
for j in xrange(c):
re = max(re, (right[j]-left[j])*height[j])
return re