这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战
问题描述
221. 最大正方形
在一个由 '0'
和 '1'
组成的二维矩阵内,找到只包含 '1'
的最大正方形,并返回其面积。
示例:
输入:matrix = [[“1”,”0”,”1”,”0”,”0”], [“1”,”0”,”1”,”1”,”1”], [“1”,”1”,”1”,”1”,”1”], [“1”,”0”,”0”,”1”,”0”]]
输出:4
分析问题
我们都知道正方形的面积等于边长的平方,要想求出最大的正方形面积,首先需要找到最大正方形的边长,然后在计算平方就好。
最直观的解法就是使用暴力法来求解。具体来说,我们遍历矩阵中的每一个元素,每次遇到1时,则将该元素作为正方形的左上角;然后根据左上角所在的行和列计算可能的最大正方形的边长(每次在下方新增一行以及在右方新增一列,判断新增的行和列是否满足所有元素都是 1)。
下面我们来看一下代码的实现。
1 | ini复制代码class Solution: |
该算法的时间复杂度是 O(m * n * min(m, n) ^ 2),其中 m 和 n 是矩阵的行数和列数;空间复杂度是O(1)。显然该算法的时间复杂度太高,下面我们来看一下如何进行优化求解。
这道题我们可以使用动态规划来求解。我们用 dp[i] [j] 表示以 (i,j) 为右下角,且只包含 1 的正方形的边长的最大值。在求出所有的dp[i] [j]的值以后,那么其中的最大值就是矩阵中只包含1的正方形的边长的最大值,其平方就是最大正方形的面积。下面我们来看一下如何来求解dp[i] [j] 。
对于矩阵中的每一个位置(i,j),检查其对应的值。
- 如果该位置是0,那么dp[i] [j] =0,因为当前位置不可能在由1组成的正方形中;
- 如果该位置是1,那么dp[i] [j] 的值由其上边,左边以及左上角三个相邻位置的值决定。即当前位置的值等于三个相邻位置元素对应的值的最小值加1。
dp[i] [j] = min( dp[i-1] [j] , dp[i] [j-1] , dp[i-1] [j-1] ) + 1
我们来看一下边界条件。当i=0或者j=0时,如果矩阵中位置为(i, j) 的值为1,那么以位置(i,j)为右下角的矩阵的边长只能是1,即此时dp[i] [j] = 1。
当matrix 为 [[“1”,”0”,”1”,”0”,”0”], [“1”,”0”,”1”,”1”,”1”], [“1”,”1”,”1”,”1”,”1”], [“1”,”0”,”0”,”1”,”0”]] 时,其状态转移矩阵如下图所示。
下面我们来看一下代码的实现。
1 | ini复制代码class Solution: |
该算法的时间复杂度是O(m*n),其中m、n分别为矩阵的行和列。空间复杂度也是O(m * n)。
本文转载自: 掘金