JZX轻语:简
LeetCode 1277 - 统计全为 1 的正方形子矩阵
发表于2024年07月16日
通过观察发现,如果一个正方形子矩阵的右下角是(i, j)
,且边长为k
,那么这个该正方形包含四个重叠的、边长为k - 1
的正方形子矩阵,分别以(i - 1, j - 1)
、(i - 1, j)
、(i, j - 1)
、(i, j)
为右下角。
因此,我们可以定义dp[i][j]
为以(i, j)
为右下角的正方形子矩阵的最大边长,那么有状态转移方程dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
(如果matrix[i][j] == 1
,否则为0
)。最后,答案即为所有dp[i][j]
的和。
class Solution:
def countSquares(self, matrix: List[List[int]]) -> int:
m, n = len(matrix), len(matrix[0])
ans = 0
dp = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
if not matrix[i][j]:
continue
dp[i][j] = min(
dp[i - 1][j] if i > 0 else 0, # 要注意边界条件, 下同
dp[i][j - 1] if j > 0 else 0,
dp[i - 1][j - 1] if i > 0 and j > 0 else 0
) + 1
ans += dp[i][j]
return ans