题目链接:Maximal Square
题目大意:给定一个零一矩阵,要求你找到里面最大的全1正方形(下面直接用矩阵表示)
题目思路:一个简单DP,对于一个矩阵,我们需要考虑这样一个问题,这个矩阵是全1矩阵,如果这个1可以往下接着延申,那么这个全1矩阵就不是最优的,所以我们需要考虑对于某个1,他能得到的最优矩阵,那么一定是这个1是当前最优矩阵的右下角,我们可以用dp[i][j]表示以这个元素为右下角的最优矩阵的边长,那么我们需要一个合理的转移方程,首先,如果该元素是0,那么直接是零了,不用讨论,只有在当前元素为1的时候才有可能出现矩阵叠加,我们考虑这样一个情况,如果这个元素是某个矩阵的右下角,那么他的上面,左边,以及斜上的某个矩阵,一定是1,那么我们去考虑他的边长,他的边长可以是他上面一些连续的1元素以及他左边的一些连续1,那么这个过程其实也就是Min(dp[i-1][j],dp[i][j-1])+1,因为正方形边长肯定是最小的一个,那么这个边长我们可以初步确定了,但是,我们这里只确定了一件事,这样的一个矩阵的最右边一列和最下边一行全是1,其他元素还没有确定,这个可以用dp[i-1][j-1]确定,这个实际上就是剩下的一些元素是否为1,如果这个小了的话,也不能够扩展到之前定的边长,所以还需要去对比这个元素的最小值,那么转移方程也就定了,也即dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1。此外,这个空间也可以优化,我们每次只会最多考虑到最多他的上一层元素,所以可以用dp[j]直接表示当前访问到的行的更新值,用prev表示之前的dp[i-j][j-1],每次更新的时候使用dp[j] = min(prev,dp[j-1],dp[j])+1,prev = dp[j] (没更新之前的dp[j]即可),代码也很好写,不过我没写,只写了这个二维的dp做法
时间复杂度&&空间复杂度:O(nm)&&O(nm)