给你一个m * n
的矩阵,矩阵中的元素不是0
就是1
,请你统计并返回其中完全由1
组成的 正方形 子矩阵的个数。示例:
一个暴力的想法是,枚举正方形的右下角,
统计有多少个右下角在(i,j)的全1正方形。
比如计算右下角在(4,4)的全1正方形的个数,可以先算出右下角在(4,4)的全1正方形的最大边长。
在下图中,最大边长等于4,那么内部的边长为3,2,1的正方形也全为1。
所以右下角在(4,4)的全1正方形个数等于4,这等于最大边长。
于是问题转换成,计算右下角在(i,j)的全1正方形的最大边长。

为方便描述,设右下角在(i,j)的全1正方形的最大边长为。
在算的时候我们遍历了图中3x3正方形的所有1。
在算的时候我们遍历了图中4×4正方形的所有1。
这个过程存在重复遍历,浪费时间,考虑用动态规划解决。

注意对应的正方形(除去右下角)可以被,,对应的正方形的并集覆盖。
(这个想法和二维前缀和的想法类似)
最终等于多少,取决于,, 三者的大小。

可得状态转移方程:
然而,当
i=0
或者 j=0
时,上式会产生负数下标 −1。为避免出现负数下标,可以在 f 矩阵的最上边添加一行 0,最左边添加一列 0,对应下标出界的状态(正方形的最大边长为0),故状态转移方程变为:
最终答案为整个矩阵的元素和。