221. 最大正方形(Maximal Square)

题解

动态规划

d p [ i ] [ j ] dp[i][j] dp[i][j]表示以第 i i i行,第 j j j列处为右下角的最大正方形的边长。
仅当该位置为 1 1 1时,才有可能存在正方形。且递推公式为:
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + 1 dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1 dp[i][j]=min(dp[i1][j1],dp[i1][j],dp[i][j1])+1
含义为若当前位置为 1 1 1,则此处可以构成的最大正方形的边长,是其正上方,左侧,和左上界三者共同约束的,且为三者中的最小值加1。

  1. 特判,若 m a t r i x matrix matrix为空,返回 0 0 0
  2. 初试化 m a t r i x matrix matrix的行 m m m,列 n n n,初始化 d p = [ [ 0 , ⋯   , 0 ] , ⋯   , [ 0 , ⋯   , 0 ] ] dp=[[0,\cdots,0],\cdots,[0,\cdots,0]] dp=[[0,,0],,[0,,0]],维度为 ( m + 1 ) ∗ ( n + 1 ) (m+1)*(n+1) (m+1)(n+1),这样便于处理。初试化最大边长 r e s = 0 res=0 res=0
  3. 遍历 d p dp dp数组,遍历行 i i i,遍历区间 [ 1 , m + 1 ) [1,m+1) [1,m+1)
    • 遍历列 j j j,遍历区间 [ 1 , n + 1 ) [1,n+1) [1,n+1)
      • m a t r i x [ i − 1 ] [ j − 1 ] = = " 1 " matrix[i-1][j-1]=="1" matrix[i1][j1]=="1",此时可能存在正方形:
        d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + 1 dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1 dp[i][j]=min(dp[i1][j1],dp[i1][j],dp[i][j1])+1
      • 并更新最大边长 r e s = m a x ( r e s , d p [ i ] [ j ] ) res=max(res,dp[i][j]) res=max(res,dp[i][j])
  4. 返回面积 r e s ∗ r e s res*res resres

例:
在这里插入图片描述
在这里插入图片描述

复杂度分析

  • 时间复杂度: O ( m ∗ n ) O(m*n) O(mn)
  • 空间复杂度: O ( m ∗ n ) O(m*n) O(mn)

Python

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=[[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

Java(待完成)

动态规划+空间优化

由动态规划的递推公式:
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + 1 dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1 dp[i][j]=min(dp[i1][j1],dp[i1][j],dp[i][j1])+1
可以得出当前位置的最大边长仅取决于上一行和左侧最大边长,因此可将空间优化到 O ( n ) O(n) O(n)
借助 p r e pre pre来保存当前位置的左侧。
注意
p r e pre pre的更新:

  • 同一行时,若当前位置为 0 0 0,需要将 p r e pre pre置为0。
  • 换行时,需要置为 0 0 0

具体看代码。

复杂度分析

  • 时间复杂度: O ( m ∗ n ) O(m*n) O(mn)
  • 空间复杂度: O ( n ) O(n) O(n)

Python

class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        if(not matrix):
            return 0
        m=len(matrix)
        n=len(matrix[0])
        res=0
        pre=0
        dp=[0]*(n+1) 
        for i in range(0,m):
            for j in range(1,n+1):
                tmp=dp[j]
                if(matrix[i][j-1]=="1"):
                    dp[j]=min(pre,dp[j-1],dp[j])+1
                    res=max(dp[j],res)
                else:
                    dp[j]=0
                pre=tmp
            pre=0
        return res*res

Java(待完成)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值