case1思想:遍历整个matrix,分别以(i,j)作为起点(作为构成的矩阵左上角元素)构建正方形(重点是如何构造这个正方形!!!),统计每次构造成的正方形的边长,选取其中最大的那个。
class Solution {
public int maximalSquare(char[][] matrix) {
int rows = matrix.length;
if(rows==0) return 0;
int cols = matrix[0].length;
//记录最大边长
int maxLen = 0;
//记录当前边长
int edgLen = 0;
//flag用于记录当前行遍历的数据是否全为'1'
boolean flag;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
//每次以matrix[i][j]作为起点时重新初始化edgLen和flag
//且只有当遍历到的数据均为'1'时才以其作为所构造正方形的左上角元素构造正方形
if(matrix[i][j]=='1'){
edgLen = 1;
flag = true;
//进行扩张,每次在原正方形的基础上再额外扩展1行和1列且.因为现在的起点左边是从(i,j)开始而不是(0,0)开始了,所有说现在扩张后的行(列)的下标应为i(j)+edglen(每次自增1)
//当能够再次扩展且再次扩展的那一行那一列还在matrix内部时再次尝试将正方形扩展一行一列
while(i+edgLen<rows&&j+edgLen<cols&&flag){
//判断新扩展的那一行的数据是否均为'1'
for(int r=i;r<=i+edgLen;r++){
if(matrix[r][j+edgLen]=='0'){
flag = false;
break;
}
}
//判断新扩展的那一列的数据是否均为'1'
for(int c=j;c<=j+edgLen;c++){
if(matrix[i+edgLen][c]=='0'){
flag = false;
break;
}
}
//若所扩展的数据均为1,满足要求,扩展成功,边长自增1
if(flag){
edgLen++;
}
}
//以点(i,j)为起点的正方形扩展结束后,更新最大边长
if(maxLen<edgLen){
maxLen = edgLen;
}
}
}
}
return maxLen*maxLen;
}
}
case2:利用DP思想
DP思想:
1.dp[i][j]表示以matrix[i-1][j-1]作为右下角元素构成的正方形的边长(这样是为了可以方便matrix中的所有数据均能利用下面的DP公式进行求解)
2.dp[i][j] = min(dp[i-1][j],dp[i-1][j-1],dp[i][j-1])+1
也就是以matrix[i][j]作为右下角元素构成的正方形的边长=分别以matrix[i][j]这个元素的左边,左上,上边的那个元素为右上角构成的正方形的边长的最小值+1
3.怎么理解这个DP公式:
因为我们这里设定的dp[i][j]表示以matrix[i][j]作为右下角元素(!!!)构成的正方形的边长
所以要以matrix[i][j]作为右下角元素(!!!)构成的正方形:它只能是以matrix[i][j]这个元素的左边,左上,上边的那个元素为右上角构成的正方形中最短的边所构成的正方形再分别扩展一列,扩展一行所形成的正方形。那么问题就来了,如何进行扩展能保证扩展后的正方形仍然满足要求:该正方形全部由’1’构成。明显(观察图)发现只有以那三个中最短的边所围成的正方形为基准然后分别再分别扩展一列,扩展一行所形成的正方形才满足要求,其他两个都不能保证
4.每次求出一个边长时就更新最大边长,最后要求的正方形的最大面积即为最大边长*最大边长
class Solution {
public int maximalSquare(char[][] matrix) {
int rows = matrix.length;
if(rows==0) return 0;
int cols = matrix[0].length;
int maxEdgLength = 0;
//这里多出来的一行一列是为了方便初始化matrix第0行和第0列的数据(也就是能为了让他们也能借助dp公式进行求解)
int[][]dp = new int[rows+1][cols+1];
for(int i=1;i<=rows;i++){
for(int j=1;j<=cols;j++){
//当matrix[i-1][j-1]=='1'时才能以其作为右下角元素构成正方形,才能去求对应正方形的边长
if(matrix[i-1][j-1]=='1'){
dp[i][j] = Math.min(Math.min(dp[i-1][j],dp[i-1][j-1]),dp[i][j-1])+1;
if(maxEdgLength<dp[i][j]){
maxEdgLength = dp[i][j];
}
}
}
}
return maxEdgLength*maxEdgLength;
}
}