其他分享
首页 > 其他分享> > 最大正方形(动态规划)

最大正方形(动态规划)

作者:互联网

题目描述:

给定一个由'0'和'1'组成的2维矩阵,返回该矩阵中最大的由全'1'组成的正方形的面积

 

示例1

 

输入:

[[1,0,1,0,0],[1,0,1,1,1],[1,1,1,1,1],[1,0,0,1,0]]

返回值:

4

题目分析:

动态规划解决

  这题让求的是由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)为右下角有可能可以构成一个更大的正方形。为啥说是有可能,因为如果我们要确定他能不能构成一个更大的正方形,还要往他的上边和左边找,看下下面的图。

 

所以我们可以得出结论,如果(i,j)是1,那么以他为右下角的最大正方形边长是:{dp[i-1][j-1],p[i-1][j],dp[i][j-1]}这3个中最小的+1。

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

如果坐标(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;

代码

 

class Solution:
    def solve(self , matrix ):
        row=len(matrix)
        col=len(matrix[0])
        dp=[[0 for _ in range(col+1)] for _ in range(row+1)]
        maxSide=0
        for i in range(1,row+1):
            for j in range(1,col+1):
                if matrix[i-1][j-1]=='1':
                    dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
                    maxSide=max(maxSide,dp[i][j])
        return maxSide*maxSide

 

 

 

 

 

标签:matrix,右下角,maxSide,正方形,range,动态,规划,dp
来源: https://www.cnblogs.com/WGJ909001/p/15023010.html