题解
动态规划
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[i−1][j−1],dp[i−1][j],dp[i][j−1])+1。
含义为若当前位置为
1
1
1,则此处可以构成的最大正方形的边长,是其正上方,左侧,和左上界三者共同约束的,且为三者中的最小值加1。
- 特判,若 m a t r i x matrix matrix为空,返回 0 0 0
- 初试化 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。
- 遍历
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[i−1][j−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[i−1][j−1],dp[i−1][j],dp[i][j−1])+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])
- 若
m
a
t
r
i
x
[
i
−
1
]
[
j
−
1
]
=
=
"
1
"
matrix[i-1][j-1]=="1"
matrix[i−1][j−1]=="1",此时可能存在正方形:
- 遍历列
j
j
j,遍历区间
[
1
,
n
+
1
)
[1,n+1)
[1,n+1):
- 返回面积 r e s ∗ r e s res*res res∗res
例:
复杂度分析
- 时间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
- 空间复杂度: O ( m ∗ n ) O(m*n) O(m∗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
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[i−1][j−1],dp[i−1][j],dp[i][j−1])+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(m∗n)
- 空间复杂度: 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