在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。
示例 1:
输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:4
示例 2:
输入:matrix = [[“0”,“1”],[“1”,“0”]]
输出:1
示例 3:
输入:matrix = [[“0”]]
输出:0
思路:典型的动态规划题。
先找递推关系。
设我们现在要知道以某个方格(i,j)为右下角的最大正方形的面积。那么这个格子所对应的最大正方形面积,只与它左上,左侧,上方的格子所对应的最大正方形面积和他自己所在位置的值有关。
当他所在位置的值为0:他所对应的最大正方形面积为0。
当他所在位置的值为1:
1.他左上,左侧,上方的格子所对应的面积均>0:那么他对应的最大正方形面积只与它左上,左侧,上方的格子所对应的最大的正方形面积的最小值k有关。且(i,j) 所对应的最大正方形面积为
[
(
k
−
1
)
+
1
]
2
[\sqrt{(k-1)}+1]^{2}
[(k−1)+1]2。
2.他左上,左侧,上方的格子所对应的最大正方形面积有一个或多个=0时:他对应的最大正方形面积为1。
用一个二重循环就可以解决,时间复杂度为 O ( n 2 ) O\left(n^{2}\right) O(n2).
比如这个4*5的格子
我们用一个二维数组来保存每个格子所对应的,以它为右下角的最大正方形面积。最左和最上方的格子对应的最大正方形面积就是它们所在位置的值。初始化如下:
经过第一轮循环,二维数组变为了下面这样:
经过第二轮循环,二维数组变成了这样:
经过第三轮循环,二维数组变成了这样:
当所有元素都遍历一遍以后,我们找出该二维数组中最大的值=4,该值即为这个4*5的格子中的最大正方形的面积。
class Solution {
public int maximalSquare(char[][] matrix) {
int len1 = matrix.length;
int len2 = matrix[0].length;
int[][] sqare = new int[len1][len2];
int[][] Matrix = new int[len1][len2];
for (int i=0;i<len1;i++)
{
for (int j=0;j<len2;j++)
{
Matrix[i][j] = Integer.parseInt(String.valueOf(matrix[i][j]));
}
}
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(i==0||j==0)
{
sqare[i][j] = Matrix[i][j];
}
}
}
for(int i=0;i<len1;i++)
{
for (int j=0;j<len2;j++)
{
if(i!=0&&j!=0)
{
int up = sqare[i-1][j];
int lf = sqare[i][j-1];
int up_lf = sqare[i-1][j-1];
if(up>0&&lf>0&&up_lf>0&&Matrix[i][j]>0)
{
ArrayList<Integer> a = new ArrayList<>();
a.add(up);a.add(lf);a.add(up_lf);
Collections.sort(a);
int k = a.get(0);
sqare[i][j] = (int)((Math.sqrt(k)+1)*((Math.sqrt(k))+1));
}
else
{
sqare[i][j] = Matrix[i][j];
}
}
}
}
int max = 0;
for(int i=0;i<len1;i++)
{
for (int j=0;j<len2;j++)
{
if(sqare[i][j]>max)
max = sqare[i][j];
}
}
return max;
}
}