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

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值