221最大正方形

题目: 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。

来源: https://leetcode-cn.com/problems/maximal-square/

法一: 自己的代码

思路: 实际上是暴力解法,先记录每个位置向上和向左的可能的正方形边长,在逐个判断是否能够构成正方形.

注意这里要判断观察出正方形的最大边长只与上边,左边,左上的格子中最大正方形的边长有关.不止与上边和左边有关!写出动态转移方程是关键

# 执行用时 :264 ms, 在所有 Python3 提交中击败了35.46% 的用户
# 内存消耗 :15.7 MB, 在所有 Python3 提交中击败了5.32%的用户
from typing import List
import math
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        # print(matrix)
        r = len(matrix)
        if r == 0:
            return 0
        c = len(matrix[0])
        memo = [[0] * c for i in range(r)]
        m = 0
        if matrix[0][0] == '1':
            memo[0][0] = (1,1,1)
            m = 1
        else:
            memo[0][0] = (0,0,0)
        # 先处理第一行和第一列
        for i in range(1,r,1):
            if matrix[i][0] == '1':
                memo[i][0] = (1,1,1+memo[i-1][0][2])
                m = 1
            else:
                memo[i][0] = (0,0,0)
        for j in range(1,c,1):
            if matrix[0][j] == '1':
                memo[0][j] = (1,1+memo[0][j-1][1],1)
                m = 1
            else:
                memo[0][j] = (0,0,0)
        # 判断其余的位置
        for i in range(1,r,1):
            for j in range(1,c,1):
                if matrix[i][j] == '1':
                    memo[i][j] = (1,1+memo[i][j-1][1],1+memo[i-1][j][2])
                else:
                    memo[i][j] = (0,0,0)
        # 判断是否在斜线上是否能够构成正方形,如果不能返回最小的正方形边长
        def judge(k,i,j):
            r = min(k[1:])
            cou = 1
            while cou < r:
                if min(memo[i-cou][j][1],memo[i][j-cou][2]) >= cou+1:
                    pass
                else:
                    return cou
                cou += 1
            return r
        for i in range(1,r,1):
            for j in range(1,c,1):
                if memo[i][j][0] == 0:
                    continue
                elif min(memo[i][j][1],memo[i][j][2]) > math.sqrt(m):
                    kkk = judge(memo[i][j], i, j)
                    if kkk > math.sqrt(m):
                        m = kkk ** 2
        return m
View Code

法二: 别人的代码

思路: 利用备忘录,先对数组加两个0边(注意这里在原list上加边不方便,所以要在备忘录上加边),方便后序的动态规划.要学会这个技巧!

from typing import List
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        if(not matrix):
            return 0
        m=len(matrix)
        n=len(matrix[0])
        res=0
        # dp作为备忘录,记录每个位置的最大正方形的边长
        # 由于在原来的list中加边不方便,在dp中加边.
        dp=[[0]*(n+1) for _ in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                if(matrix[i-1][j-1]=="1"):
                    # 动态转移方程.
                    dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1
                    res=max(dp[i][j],res)
        return res*res
if __name__ == '__main__':
    duixiang = Solution()
    # a = duixiang.maximalSquare([["1","0","1","0","0"],
    #                             ["1","0","1","1","1"],
    #                             ["1","1","1","0","1"],
    #                             ["1","0","1","1","1"]]
    #                           )
    a = duixiang.maximalSquare([["0","1","1","0","1"],
                                ["1","1","0","1","0"],
                                ["0","1","1","1","0"],
                                ["1","1","1","1","0"],
                                ["1","1","1","1","1"],
                                ["0","0","0","0","0"]]
                              )
    print(a)
View Code

ttt

猜你喜欢

转载自www.cnblogs.com/xxswkl/p/12142020.html