统计全为1的正方形子矩阵
0x1 题目详情
给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 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.
0x2 解题思路
一看到这道题,我立马想起来以前做过的一道题,在一个m*n的矩形中,找到由1构成的最大正方形的边长。跟这道题神似。那道题是用动态规划。虽然我不知道状态状态转移方程咋写出来的。但是这道题仍然可以使用求最大正方形边长的思路。
求一个矩阵中由1构成的最大正方形时:我们需要求出每个位置上所能构成的最大正方形,我们可以已当前求的位置作为正方形的右下角,来看看在右下角固定时,该位置能够构成的正方形最多有多大。
这时,能够构成的最大正方形由固定位置的左边、上边和左上角的最大正方形决定。这里可能有点抽象。在下图中,我们将固定的右下角分配为橘色。左边分配为蓝色,上边分配为绿色,左上角分配为黄色。(注意上述中所有的正方形都是在右下角固定时求来的)。
如果你看懂了如何求最大正方形边长,那么这道题肯定不会难住你。一个位置能够的子矩阵数量不就等于构成的最大正方形边长吗?没有任何转换,只要在求边长的过程中统计最大边长和就行啦。
0x3 代码实现
知道了状态转移方程,写代码就非常简单了。
$dp[i][j]=Math.min(Math.min(dp[i][j-1],dp[i-1][]j),dp[i-1][]j-1)$
时间复杂为$O(MN)$,空间复杂度为$O(MN)$,当然空间这里仍有优化的空间。
0x4 课后总结
我觉得吧,这个状态转义方程全靠规律总结出来的,我一般都是先写递归,然后再改成dp,这种方式简直无脑,后续遇到相关的题目我会介绍的奥。至于我为什么把它分到几何题呢,因为求最大正方形这一类题目都可以靠最大边长这个方式解...
Last updated
Was this helpful?