Leetcode刷题笔记-最大矩形,最大正方形

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sengo_GWU/article/details/88374609

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.

  1. dp[0][j] = matrix[0][j] (topmost row);
  2. dp[i][0] = matrix[i][0] (leftmost column);
  3. For i > 0 and j > 0: if matrix[i][j] = 0dp[i][j] = 0; if matrix[i][j] = 1dp[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

猜你喜欢

转载自blog.csdn.net/Sengo_GWU/article/details/88374609