題目
在一個由 0 和 1 組成的二維矩陣內,找到只包含 1 的最大正方形,並返回其面積。
示例:
輸入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
輸出: 4
兩種思路:
一:暴力篩查
- 計算出每一個點(以該點爲正方形的左上點)最大正方形面積。
代碼這裏不寫了,時間複雜度過高。
第二種思路:動態規劃
-
創建同樣大小的二維數組int[][] dp,數組存放的值爲
dp[i][j] 表示以該點爲正方形右下角(或者說該點左上方存在最大正方形)的最大正方形邊長 -
那麼遍歷dp二維數組中最大值的二次方便是本題的答案
動態規劃問題:最爲關鍵是狀態方程的獲取,下面是大致思路
- 1:當(i0 || j0)時(即該點位於二維數組的邊界),若matrix[i][j] 爲0,則dp[i][j]爲0;若matrix[i][j] 爲1,則dp[i][j]爲1;
- 2:當 (i > 0 && j > 0) 時(即該點位於二維數組的內部),若matrix[i][j] 爲0,則dp[i][j]爲0;若matrix[i][j] 爲1,你則需要考察dp[i-1][j],dp[i][j-1],dp[i-1][j-1] 這三個值的大小;
- dp[i-1][j] 表示 dp[i][j] 左側能獲取到的正方形最大邊長 (在座標系中你可以理解爲x軸方向)
- dp[i][j-1] 表示 dp[i][j] 上方能獲取到的正方形最大邊長 (在座標系中你可以理解爲y軸方向)
- dp[i-1][j-1] 表示 dp[i][j] 內部能獲取的正方形最大邊長
而 matrix[i][j] (元素值爲1)點,左上方能構成最大正方形,取決於上述三者的最短板。
所以不難得出
- dp[i][j] = Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1] ) +1;
代碼如下:
class Solution {
public int maximalSquare(char[][] matrix) {
// 動態規劃的思想
int maximal = 0;
int m = matrix.length;
if(m == 0){
return maximal;
}
int n = matrix[0].length;
// 創建二維數組,該數組中存放元素值表示
// dp[i][j] 點左上方到該點最大正方形的邊長
int[][] dp = new int[m][n];
for(int i = 0; i < m; i++ ){
for(int j = 0; j < n; j++){
if(i == 0 || j == 0 || matrix[i][j] == '0'){
int value = matrix[i][j] - '0';
dp[i][j] = value;
} else {
dp[i][j] = Math.min(dp[i-1][j],Math.min(dp[i][j-1],dp[i-1][j-1])) + 1;
}
maximal = Math.max(dp[i][j],maximal);
}
}
return maximal*maximal;
}
}