题目地址:
https://www.lintcode.com/problem/maximal-square-ii/description
给定一个二维 0 − 1 0-1 0−1矩阵 A A A,求其所含的最大的左上到右下对角线(主对角线)全为 1 1 1,其余位置全为 0 0 0的方阵的面积。
思路是动态规划。我们考虑以
A
[
i
]
[
j
]
A[i][j]
A[i][j]为右下角的方阵,以它为右下角的满足条件的最大方阵的边长,取决于:
1、以
A
[
i
−
1
]
[
j
−
1
]
A[i-1][j-1]
A[i−1][j−1]满足条件的方阵边长;
2、其上方有多少个
0
0
0;
3、其左方有多少个
0
0
0。
设
f
[
i
]
[
j
]
f[i][j]
f[i][j]为以
A
[
i
]
[
j
]
A[i][j]
A[i][j]为右下角的方阵中满足条件的最大方阵的边长,设
g
[
i
]
[
j
]
g[i][j]
g[i][j]为
A
[
i
]
[
j
]
A[i][j]
A[i][j]上方的
0
0
0的个数(包括
A
[
i
]
[
j
]
A[i][j]
A[i][j]自己),设
h
[
i
]
[
j
]
h[i][j]
h[i][j]为
A
[
i
]
[
j
]
A[i][j]
A[i][j]左方的
0
0
0的个数(包括
A
[
i
]
[
j
]
A[i][j]
A[i][j]自己)。那么就有:
g
[
i
]
[
j
]
=
{
0
,
A
[
i
]
[
j
]
=
1
1
+
g
[
i
−
1
]
[
j
]
,
A
[
i
]
[
j
]
=
0
h
[
i
]
[
j
]
=
{
0
,
A
[
i
]
[
j
]
=
1
1
+
h
[
i
]
[
j
−
1
]
,
A
[
i
]
[
j
]
=
0
f
[
i
]
[
j
]
=
{
0
,
A
[
i
]
[
j
]
=
0
1
+
min
{
g
[
i
−
1
]
[
j
]
,
h
[
i
]
[
j
−
1
]
,
f
[
i
−
1
]
[
j
−
1
]
}
,
A
[
i
]
[
j
]
=
1
g[i][j]=\begin{cases}0,A[i][j]=1\\ 1+g[i-1][j],A[i][j]=0\end{cases}\\h[i][j]=\begin{cases}0,A[i][j]=1\\ 1+h[i][j-1],A[i][j]=0\end{cases}\\f[i][j]=\begin{cases}0,A[i][j]=0\\ 1+\min\{g[i-1][j],h[i][j-1],f[i-1][j-1]\},A[i][j]=1\end{cases}
g[i][j]={0,A[i][j]=11+g[i−1][j],A[i][j]=0h[i][j]={0,A[i][j]=11+h[i][j−1],A[i][j]=0f[i][j]={0,A[i][j]=01+min{g[i−1][j],h[i][j−1],f[i−1][j−1]},A[i][j]=1代码如下:
public class Solution {
/**
* @param matrix: a matrix of 0 an 1
* @return: an integer
*/
public int maxSquare2(int[][] matrix) {
// write your code here
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int m = matrix.length, n = matrix[0].length;
int res = 0;
int[][] up0 = new int[m][n], left0 = new int[m][n], dp = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 1) {
up0[i][j] = left0[i][j] = 0;
} else {
up0[i][j] = left0[i][j] = 1;
if (i > 0) {
up0[i][j] += up0[i - 1][j];
}
if (j > 0) {
left0[i][j] += left0[i][j - 1];
}
}
if (matrix[i][j] == 0) {
dp[i][j] = 0;
} else {
dp[i][j] = 1;
if (i > 0 && j > 0) {
int min0 = Math.min(left0[i][j - 1], up0[i - 1][j]);
dp[i][j] += Math.min(dp[i - 1][j - 1], min0);
}
}
res = Math.max(res, dp[i][j]);
}
}
// 求面积,要平方一下
return res * res;
}
}
时空复杂度 O ( m n ) O(mn) O(mn)。