题目描述
显而易见地可以用dp来写,问题在于如何考虑状态转移方程
思路 & 代码
首先再加一层外墙,就不用边界判断了 maxSqure[i]:以当前格子为右下角的正方形,可达到的最大边长 这是由左、上、左上三个格子的maxSqure来决定的(类似木桶短板) 借用一下leetcode题解中 lzhlyle 大佬的图,这个0限制我没太理解,这里说说我的理解吧: 三个图分别代表全部可能的三种情况 :左上小了、上小了、左小了 对于这三种情况,我们发现采取的值都遵循这个规律:直接取三者中最小的值即可 由此可以得到状态转移方程(见代码)
class Solution {
public int maximalSquare ( char [ ] [ ] matrix) {
int m = matrix. length;
int n = matrix[ 0 ] . length;
int maxSide = 0 ;
int [ ] [ ] maxSqure = new int [ m + 1 ] [ n + 1 ] ;
for ( int i = 1 ; i <= m; i++ ) {
for ( int j = 1 ; j <= n; j++ ) {
if ( matrix[ i- 1 ] [ j- 1 ] == '1' ) {
maxSqure[ i] [ j] = Math . min ( Math . min ( maxSqure[ i- 1 ] [ j- 1 ] , maxSqure[ i- 1 ] [ j] ) , maxSqure[ i] [ j- 1 ] ) + 1 ;
maxSide = Math . max ( maxSqure[ i] [ j] , maxSide) ;
}
}
}
return maxSide * maxSide;
}
}
时间复杂度 O(m * n),空间复杂度 O(m * n)
更新版
class Solution {
public int maximalSquare ( char [ ] [ ] matrix) {
int [ ] [ ] maxSquareSize = new int [ matrix. length + 1 ] [ matrix[ 0 ] . length + 1 ] ;
int resSize = 0 ;
for ( int i = 1 ; i <= matrix. length; i++ ) {
for ( int j = 1 ; j <= matrix[ 0 ] . length; j++ ) {
if ( matrix[ i - 1 ] [ j - 1 ] == '1' ) {
maxSquareSize[ i] [ j] = Math . min ( maxSquareSize[ i - 1 ] [ j] , maxSquareSize[ i] [ j - 1 ] ) ;
maxSquareSize[ i] [ j] = Math . min ( maxSquareSize[ i] [ j] , maxSquareSize[ i - 1 ] [ j - 1 ] ) ;
resSize = Math . max ( resSize, ++ maxSquareSize[ i] [ j] ) ;
}
}
}
return resSize * resSize;
}
}