问题描述:
给你一个 m * n
的矩阵,矩阵中的元素不是 0
就是 1
,请你统计并返回其中完全由 1
组成的 正方形
子矩阵的个数
。
示例 1:
输入:matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
输出:15
解释:
边长为 1 的正方形有 10 个。
边长为 2 的正方形有 4 个。
边长为 3 的正方形有 1 个。
正方形的总数 = 10 + 4 + 1 = 15.
提示:
1 <= arr.length <= 300
1 <= arr[0].length <= 300
0 <= arr[i][j] <= 1
问题分析:
题目已经给出提示了动态规划,现在就直接给出解法,先给出dp方程式:(现在用A
表示原始的 matrix
)
- 设
dp[i][j]
表示以A[i][j]
为右下角组成的正方形个数总和
。 - 现在求
dp[i][j]
的值,怎么求? 很显然它的值dp[i-1][j-1]
、dp[i-1][j]
和dp[i][j-1]
(分别是:左上角、左边、上边)三个值有关。在这里,如果比较想直观的理解,可以画一个图,如下图:(来自参考链接2)
- 现在不难看出,
dp[i][j]
的值应该是dp[i-1][j-1]
、dp[i-1][j]
和dp[i][j-1]
三值中的最小的一个
然后+1
即可。 - 所以:
IfA[i][j] == 0
,dp[i][j] =0
,也就是没有正方形。
IfA[i][j] == 1
,dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1
- 最后一步就是把dp 求和即可得出最后的结果。
Python3实现:
class Solution:
def countSquares(self, matrix):
dp = matrix # 这一步没必要,为了好看换成dp
for i in range(1, len(dp)):
for j in range(1, len(dp[0])):
dp[i][j] *= min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
return sum(map(sum, dp))
if __name__ == '__main__':
solu = Solution()
matrix =[
[0, 1, 1, 1],
[1, 1, 1, 1],
[0, 1, 1, 1]]
声明: 总结学习,有问题或不当之处,可以批评指正哦,谢谢。
题目链接:https://leetcode-cn.com/problems/count-square-submatrices-with-all-ones
参考链接1:https://leetcode.com/problems/count-square-submatrices-with-all-ones/discuss/441306/Python-DP-solution
参考链接2:https://leetcode.com/problems/count-square-submatrices-with-all-ones/discuss/447967/JAVA-with-explanation-DP-7ms-O(m*n)-space-100