算法题分享 | 最大正方形

18 阅读2分钟

iPad壁纸🗓文字篇19_1_舞木子_来自小红书网页版.jpg

题目

在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。

示例 1:

输入: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出: 4

示例 2:

输入: matrix = [["0","1"],["1","0"]]
输出: 1

示例 3:

输入: matrix = [["0"]]
输出: 0

 

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 300
  • matrix[i][j] 为 '0' 或 '1'

题解

解题思路

这道题可以使用动态规划来解决。

假如用 dp[i][j] 表示以第 i 行第 j 列元素为右下角的只包含 '1' 最大正方形的边长,现在要考虑如何求得该值,既然是右下角,所以只需要考虑如何通过当前元素的左、左上、上这三个元素对应的 dp 值来得到 dp[i][j] 的值。

状态转移方程
如果 matrix[i][j] == '0',那么 dp[i][j] 显然是为 0 的,这点很好理解,主要是需要考虑 matrix[i][j] == '1'的情况。可以观察到,dp[i][j] 可以从左、左上、上这三个元素对应 dp 值中取最小值再加 1 得到,因此当 matrix[i][j] == '1' 时状态转移方程如下:

dp[i][j] = min(dp[i][j-1], dp[i-1][j-1], dp[i-1][j]) + 1

边界值
当 i = 0 时,由于上侧和左上侧没有元素,所以 dp[i-1][j-1], dp[i-1][j] 可以当做 0 处理;
当 j = 0 时,由于左侧和左上侧没有元素,所以 dp[i][j-1], dp[i-1][j-1] 可以当做 0 处理。

从矩形左上角第一个元素开始,逐一处理即可,最终 dp 数组中的最大值即为最大正方形的边长,平方求得面积返回即可。

代码

class Solution {
    public int maximalSquare(char[][] matrix) {
        
        int m = matrix.length;
        int n = matrix[0].length;

        int[][] dp = new int[m + 1][n + 1];
        int ans = 0;

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (matrix[i-1][j-1] == '0') {
                    continue;
                }

                dp[i][j] = Math.min(dp[i-1][j], Math.min(dp[i-1][j-1], dp[i][j-1])) + 1;
                if (dp[i][j] > ans) {
                    ans = dp[i][j];
                }
            }
        }

        return ans * ans;

    }
}

复杂度分析

  • 时间复杂度:O(mn)
    m 为矩形的行数,n 为矩形的列数。
  • 空间复杂度:O(mn) 使用 dp 数组的空间开销。

优质项目推荐

推荐一个可用于练手、毕业设计参考、增加简历亮点的项目。

lemon-puls/txing-oj-backend: Txing 在线编程学习平台,集在线做题、编程竞赛、即时通讯、文章创作、视频教程、技术论坛为一体

公众号

有兴趣可以关注公众号一起学习更多的干货哈!

扫码_搜索联合传播样式-白色版.png