7 最大的以1为边界的正方形
来源:LeetCode第1139题
难度:中等
描述:给你一个由若干0和1组成的二维网格grid,请你找出边界全部由1组成的最大正方形子网格,并返回该子网格中的元素个数,若不存在,则返回0;
思路:申请三个空间,第一个二维空间dp1[i][j],这个空间表示第i行第j列在[i][j]这个位置前面(左边)连续1的个数包括自己。第二个二维空间dp2[i][j],这个空间表示第i行第j列在[i][j]这个位置上面联系1的个数包括自己。第三个二维空间dp3[i][j]表示以[i][j]为右下角的最大正方形边长。
//首先定义一个函数,输入值时grid的二维数组,返回值是最大正方形元素的个数
public int maxSquare(int [][]grid)
{
//求grid矩阵的行数
int row=grid.length;
//求grid矩阵的列数,默认为长方形
int column=grid[0].length;
//生成3个动态数组
//第一个动态数组dp1[i][j]表示[i][j]位置处左边连续1的个数
int [][]dp1=new int[row][column];
//第二个动态数组dp2[i][j]表示[i][j]位置处上方连续1的个数
int [][]dp2=new int[row][column];
//第三个动态数组dp3[i][j]表示以[i][j]为右下角的最大正方形面积,围成的最大正方形边长*边长
int [][]dp3=new int[row][column];
//首先进行dp1[i][j]数组第一列的初始化,若第一个元素为1,则dp1[i][0]=1,否则dp1[i][0]=0;
for(int i=0;i<grid.length;i++)
{
if(grid[i][0]==1)
{
dp1[i][0]=1;
}else
{
dp1[i][0]=0;
}
}
//其次进行dp2[i][j]数组第一行的初始化,若第一个元素为1,则dp2[0][i]=1,否则dp2[0][i]=0;
for(int i=0;i<grid[0].length;i++)
{
if(grid[0][i]==1)
{
dp2[0][i]=1;
}else
{
dp2[0][i]=0;
}
}
//进行dp1[i][j]动态数组的递推公式,如果grid[i][j]==1,则dp1[i][j]=dp1[i][j-1]+1,否则为0
for(int i=0;i<grid.length;i++)
{
for(int j=1;j<grid[i].length;j++)
{
if(grid[i][j]==1)
{
dp1[i][j]=dp1[i][j-1]+1;
}else
{
dp1[i][j]=0;
}
}
}
//进行dp2[i][j]动态数组的递推公式,如果grid[i][j]==1,dp2[i][j]=dp[i-1][j]+1;,否则为0
for(int i=1;i<grid.length;i++)
{
for(int j=0;j<grid[i].length;j++)
{
if(grid[i][j]==1)
{
dp2[i][j]=dp[i-1][j]+1;
}else
{
dp2[i][j]=0;
}
}
}
//进行dp3[i][j]动态数组第一列的初始化,若对应位置为1,则dp3[i][0]=1;
for(int i=0;i<grid.length;i++)
{
if(grid[i][0]==1)
{
dp3[i][0]=1;
}else
{
dp3[i][0]=0;
}
}
//进行dp3[i][j]动态数组第一行的初始化,若对应位置为1,则dp3[0][i]=1;
for(int i=1;i<grid[0].length;i++)
{
if(grid[0][i]==1)
{
dp3[0][i]=1;
}else
{
dp3[0][i]=0;
}
}
//定义变量maxsize表示从[i][j]位置上下寻找到的最大正方形边长
int maxside=0;
//记录最大的正方形边长,并最后返回
int maxsquqre=0;
for(int i=1;i<grid.length;i++)
{
for(int j=1;j<grid[i].length;i++)
{
//如果grid[i][j]==0,则以[i][j]无法构成正方形,dp3[i][j]=0;
if(grid[i][j]==0)
{
dp3[i][j]=0;
}else
{
//从[i][j]位置左边和上边寻找最小连续1的个数,从而可以构成最大边长
maxside=Math.min(dp1[i][j],dp2[i][j]);
for(int i=maxside;i>=0;i--)
{
//不断由最大变成找到最左边的位置[i][j-maxsize+1]并且求解该位置竖向上方1的个数dp2[i][j-maxsize+1],找到最上边的位置[i-maxsize+1][j]并且求解该位置左边连续1的个数,如果均大于maxsize,表示能构成正方形,否则继续缩小maxsize,不断进行寻找,一旦找到满足条件的,记录入dp3中,并与maxsquare进行对比后break跳出循环
if(dp2[i][j-maxsize+1]>=maxsize&&dp1[i-maxsize+1][j]>=maxsize)
{
dp3[i][j]=i*i;
maxsquare=Math.max(maxsquare,dp3[i][j]);
break;
}
}
}
}
}
return maxsqure;
}