問題描述
在一個二維0
1
矩陣中找到全為1
的最大正方形,返回其邊長。
輸入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
輸出:
2
思路:
動態規劃,構造一個等大小的dp[n][m]
矩陣,dp[i][j]
表示以matrix[i][j]
為右下角的全1正方形的邊長。初始化dp[i][0]
和dp[0][j]
分別為matrix[i][0]
和matrix[0][j]
,因為以邊緣這一行一列中的點為右下角的全1
正方形邊長只有0
和1
兩種情況,分別由他們本身是0
還是1
決定。初始化之后開始遍歷這個dp矩陣,如果matrix[i][j]
為0
,則dp[i][j]
為1
,如果matrix[i][j]
為1
,則dp[i][j]=min{dp[i-1][j],dp[i][j-1],dp[i-1][j-1]}+1
,這一步可以這樣理解:
矩陣示意圖
只有滿足
matrix[i][j]
左方上方和左上方三個地方的正方形邊長為2
的時候,它的邊長才能為3
,任意一個為1
,則它的邊長為2
,所以取三者最小值+1
就是以該點為右下角的全1
正方形邊長。最后只用遍歷dp
矩陣找出最大值即可。
代碼:
public class Solution {
public int FindAllOneSquare(int [][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int dp[][] = new int[m][n];
for (int i = 0; i < m; i++){
dp[i][0] = matrix[i][0];
}
for (int j = 0; j < n;j++){
dp[0][j] = matrix[0][j];
}
for (int i=1; i < m; i++){
for (int j = 1; j < n; j++){
if (matrix[i][j] == 0)
dp[i][j] = 0;
else {
dp[i][j] = Math.min(dp[i-1][j-1],
Math.min(dp[i][j-1], dp[i-1][j])) + 1;
}
}
}
int max = 0;
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (dp[i][j] > max)
max = dp[i][j];
}
}
return max;
}
}