题目地址:
https://www.lintcode.com/problem/maximal-square/description
给定一个二维 0 − 1 0-1 0−1矩阵 A A A,求其中由 1 1 1构成的最大正方形的面积。
思路是动态规划。设
f
[
i
]
[
j
]
f[i][j]
f[i][j]是以
A
[
i
]
[
j
]
A[i][j]
A[i][j]为右下角的最大正方形的边长。那么很显然当
i
=
0
i=0
i=0或
j
=
0
j=0
j=0时,
f
[
i
]
[
j
]
=
A
[
i
]
[
j
]
f[i][j]=A[i][j]
f[i][j]=A[i][j]。否则的话,我们试图将
f
[
i
]
[
j
]
f[i][j]
f[i][j]与
f
[
i
−
1
]
[
j
]
f[i-1][j]
f[i−1][j]和
f
[
i
]
[
j
−
1
]
f[i][j-1]
f[i][j−1]联系起来。
如果
f
[
i
−
1
]
[
j
]
=
f
[
i
]
[
j
−
1
]
=
x
f[i-1][j]=f[i][j-1]=x
f[i−1][j]=f[i][j−1]=x,那么说明
f
[
i
]
[
j
]
≤
x
+
1
f[i][j]\le x+1
f[i][j]≤x+1,并且当且仅当
A
[
i
−
x
]
[
j
−
x
]
=
1
A[i-x][j-x]=1
A[i−x][j−x]=1时取等号,若
A
[
i
−
x
]
[
j
−
x
]
≠
1
A[i-x][j-x]\ne 1
A[i−x][j−x]=1,则
f
[
i
]
[
j
]
=
x
f[i][j]=x
f[i][j]=x;
如果
f
[
i
−
1
]
[
j
]
≠
f
[
i
]
[
j
−
1
]
f[i-1][j]\ne f[i][j-1]
f[i−1][j]=f[i][j−1],不妨设
f
[
i
−
1
]
[
j
]
<
f
[
i
]
[
j
−
1
]
f[i-1][j]<f[i][j-1]
f[i−1][j]<f[i][j−1],那么显然
f
[
i
]
[
j
]
≤
f
[
i
−
1
]
[
j
]
+
1
f[i][j]\le f[i-1][j]+1
f[i][j]≤f[i−1][j]+1,并且由于
A
[
i
−
f
[
i
−
1
]
[
j
]
]
[
j
−
f
[
i
−
1
]
[
j
]
]
=
1
A[i-f[i-1][j]][j-f[i-1][j]]=1
A[i−f[i−1][j]][j−f[i−1][j]]=1(原因是
f
[
i
−
1
]
[
j
]
<
f
[
i
]
[
j
−
1
]
f[i-1][j]<f[i][j-1]
f[i−1][j]<f[i][j−1]),所以
f
[
i
]
[
j
]
=
f
[
i
−
1
]
[
j
]
+
1
f[i][j]= f[i-1][j]+1
f[i][j]=f[i−1][j]+1。
代码如下:
public class Solution {
/**
* @param matrix: a matrix of 0 and 1
* @return: an integer
*/
public int maxSquare(int[][] matrix) {
// write your code here
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
// 存储最长边长
int res = 0;
int[][] dp = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (i == 0 || j == 0) {
dp[i][j] = matrix[i][j];
} else if (matrix[i][j] == 0) {
dp[i][j] = 0;
} else {
int left = dp[i][j - 1], up = dp[i - 1][j];
if (left != up) {
dp[i][j] = Math.min(left, up) + 1;
} else {
dp[i][j] = matrix[i - left][j - left] == 1 ? left + 1 : left;
}
}
// 更新已经获得的最长边长
res = Math.max(res, dp[i][j]);
}
}
// 要返回面积而不是边长
return res * res;
}
}
时空复杂度 O ( m n ) O(mn) O(mn)。