在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
示例:
输入: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 输出: 4
1、暴力法
计算二维矩阵里,每一个 正方形的面积,判断是否只包含1,如果是算出面积,并取面积最大者的值。
public int solve(char[][] matrix, int startRow, int startCol)
{
int rowLen = matrix.length;
int colLen = matrix[0].length;
int len = rowLen < colLen ? rowLen : colLen; // 取较小的边长
int maxArea = 0; // 最大面积
int currArea = 0; //当前的面积
for (int i=0; i<len; i++) // 边长范围
{
if (!isLegal(matrix, startRow, startCol, i))
{
startCol++;
// 改变正方形起始顶点的位置
if (startCol == colLen) // 到达最后一列
{
startRow++;
if (startRow == rowLen) // 到达最后一行
break;
startCol = 0;
}
i = -1;
}
else
{
currArea = (i+1)*(i+1);
maxArea = maxArea > currArea ? maxArea : currArea;
}
}
return maxArea;
}
// 判断以startRow,startCol为起点的正方形是否只包含1
boolean isLegal(char[][] matrix, int startRow, int startCol, int len)
{
boolean rowEnd = startRow + len >= matrix.length ? false : true;
boolean colEnd = startCol + len >= matrix[0].length ? false : true;
if (rowEnd==false || colEnd==false)
return false;
for (int i=startRow; i<=startRow+len; i++)
{
for (int j=startCol; j<=startCol+len; j++)
{
if (matrix[i][j] != '1')
return false;
}
}
return true;
}
public int maximalSquare(char[][] matrix)
{
if (matrix == null || matrix.length == 0)
return 0;
return solve(matrix, 0, 0);
}
2、动态规划
状态转移方程: dp[i][j] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]);
public int maximalSquare(char[][] matrix)
{
if (matrix == null || matrix.length == 0)
return 0;
int m = matrix.length; // 行数
int n = matrix[0].length; // 列数
int maxLen = 0;
// dp[i][j]表示以第i行第j列为右下角所能构成的最大正方形边长
int[][] dp = new int[m+1][n+1];
for (int i=1; i<=m; i++)
{
for (int j=1; j<=n; j++)
{
if (matrix[i-1][j-1] == '1')
{
dp[i][j] = 1 + Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1]));
maxLen = Math.max(maxLen, dp[i][j]);
}
}
}
return maxLen * maxLen;
}