最大正方形(maximal-square)
Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.
示例:
輸入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
輸出: 4
如圖
代碼
方法一:暴力法
由於正方形的面積等於邊長的平方,因此要找到最大正方形的面積,首先需要找到最大正方形的邊長,然後計算最大邊長的平方即可。
暴力法是最簡單直觀的做法,具體做法如下:
遍歷矩陣中的每個元素,每次遇到 1,則將該元素作爲正方形的左上角;
確定正方形的左上角後,根據左上角所在的行和列計算可能的最大正方形的邊長(正方形的範圍不能超出矩陣的行數和列數),在該邊長範圍內尋找只包含 1 的最大正方形;
每次在下方新增一行以及在右方新增一列,判斷新增的行和列是否滿足所有元素都是 1。
class Solution {
public int maximalSquare(char[][] matrix) {
int maxSide = 0;
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return maxSide;
}
int rows = matrix.length, columns = matrix[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (matrix[i][j] == '1') {
// 遇到一個 1 作爲正方形的左上角
maxSide = Math.max(maxSide, 1);
// 計算可能的最大正方形邊長
int currentMaxSide = Math.min(rows - i, columns - j);
for (int k = 1; k < currentMaxSide; k++) {
// 判斷新增的一行一列是否均爲 1
boolean flag = true;
if (matrix[i + k][j + k] == '0') {
break;
}
for (int m = 0; m < k; m++) {
if (matrix[i + k][j + m] == '0' || matrix[i + m][j + k] == '0') {
flag = false;
break;
}
}
if (flag) {
maxSide = Math.max(maxSide, k + 1);
} else {
break;
}
}
}
}
}
int maxSquare = maxSide * maxSide;
return maxSquare;
}
}
方法二:動態規劃
class Solution {
public int maximalSquare(char[][] matrix) {
/**
dp[i][j]表示以第i行第j列爲右下角所能構成的最大正方形邊長, 則遞推式爲:
dp[i][j] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]);
**/
int m = matrix.length;
if(m < 1) return 0;
int n = matrix[0].length;
int max = 0;
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]));
max = Math.max(max, dp[i][j]);
}
}
}
return max*max;
}
}