【数据结构和算法】动态规划解最大正方形

最大正方形

http://www.nowcoder.com/practice/0058c4092cec44c2975e38223f10470e

动态规划解决

这题让求的是由1围成的最大正方形,最容易想到的一种方式就是暴力求解。解决方式就是如果某个位置是1,就以他为正方形左上角,然后沿着右边和下边找最大的正方形,并且还要保证围成的正方形中所有的数字都是1。

这种虽然容易想到但代码不太好写,并且时间复杂度也比较高。下面我们来看另一种实现方式,使用动态规划来解决。

定义二维数组dp[m][n],其中dp[i][j]表示的是在矩阵中以坐标(i,j)为右下角的最大正方形边长。如果我们想求dp[i][j],需要判断矩阵中matrix[i][j]的值。

如果matrix[i][j]是0就没法构成正方形,所以dp[i][j]=0。

如果matrix[i][j]是1,说明他可以构成一个正方形,并且这个正方形的边长最小是1。

  • 如果我们想求最大值,还需要判断他左上角的值dp[i-1][j-1],如果dp[i-1][j-1]是0,那么以坐标(i,j)为右下角的最大正方形边长就是1,如下图所示

图片说明

  • 如果左上角的值dp[i-1][j-1]不是0,也就是说他也可以构成正方形,那么以坐标(i,j)为右下角有可能可以构成一个更大的正方形。为啥说是有可能,因为如果我们要确定他能不能构成一个更大的正方形,还要往他的上边和左边找,看下下面的图。 图片说明

有可能是下面这种情况,就是左边或者上边的某一个高度小于dp[i-1][j-1]的值,要想构成最大的正方形我们只能取最小的。 图片说明

也有可能是下面这种,就是左边和上边的高度都不小于dp[i-1][j-1]的值。 图片说明

所以我们可以得出结论,如果(i,j)是1,那么以他为右下角的最大正方形边长是

{dp[i-1][j-1],上边的高度,左边的高度}这3个中最小的+1。

这里有个问题就是,如果(i,j)是1,我们有必要往他的上边和左边查找吗,很明显没必要,上边可以用dp[i-1][j]来代表,左边可以用dp[i][j-1]来代表。(注意这里dp[i-1][j]并不是上边为1的高度,dp[i-1][j]只会小,不会大,可以想一下为什么可以代表)

所以我们可以找出递推公式

如果坐标(i,j)为0,

则dp[i][j]=0;

如果坐标(i,j)为1,

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

为了防止一些不必要的边界条件判断,我把dp数组的长和宽都增加了1,来看下代码

 public int solve (char[][] matrix) {
    //二维矩阵的宽和高
    int height = matrix.length;
    int width = matrix[0].length;
    int[][] dp = new int[height + 1][width + 1];
    int maxSide = 0;//最大正方形的宽
    for (int i = 1; i <= height; i++) {
        for (int j = 1; j <= width; j++) {
            if (matrix[i - 1][j - 1] == '1') {
                //递推公式
                dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i][j - 1])) + 1;
                //记录最大的边长
                maxSide = Math.max(maxSide, dp[i][j]);
            }
        }
    }
    //返回正方形的面积
    return maxSide * maxSide;
}

看一下运行结果 图片说明

时间复杂度:O(m*n),m,n表示矩阵的行和列 空间复杂度:O(m*n)

如果觉得有用就给个赞吧,还可以关注我的《牛客博客》查看更多的详细题解

数据结构和算法 文章被收录于专栏

专注于算法题的讲解,包含常见数据结构,排序,查找,动态规划,回溯算法,贪心算法,双指针,BFS和DFS等等。

全部评论
数组越界怎么说?
1 回复 分享
发布于 2022-01-15 09:52
太漂亮了
点赞 回复 分享
发布于 2022-11-18 09:26 上海
答案不对吧,例如[[1,1,1],[1,0,1],[1,1,1]],对于最右下角的1而言,其左上角为0,按答主所言,其正方形最大值应该为1,其实为3
点赞 回复 分享
发布于 2022-02-13 22:13
只依赖上一层结果,时间复杂度可以到o(n)吧
点赞 回复 分享
发布于 2022-02-09 14:49
妙啊! 我咋想不出来呢。真的是 越刷越 觉得自己笨
点赞 回复 分享
发布于 2021-12-01 17:06
牛蛙牛蛙
点赞 回复 分享
发布于 2021-08-17 10:16
牛牛牛
点赞 回复 分享
发布于 2021-07-09 15:22

相关推荐

07-15 18:09
门头沟学院 Java
点赞 评论 收藏
分享
Rena1ssanc...:对的,要是面评没太烂,勤更新简历等捞就行了,腾讯可以无限复活
点赞 评论 收藏
分享
06-12 17:46
门头沟学院 Java
运营你豪哥:来说重点: ​1.项目前置,时间倒序。​​ 2.​项目描述强化结果与量化效果(STAR原则里的R)。​​ ​3.个人技能精炼,明确掌握程度,突出核心。​​ ​4.增加强有力开头的个人总结部分。​​ 5.​优化教育背景(成绩排名)、合并奖项与活动。​​
听劝,我这个简历该怎么改...
点赞 评论 收藏
分享
07-13 14:45
南华大学 Java
北斗导航Compas...:英文和中文之间加个空格,有的句子有句号 有的没。其他没啥问题
点赞 评论 收藏
分享
评论
33
10
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务