LeetCode數組篇(五):最大正方形問題(動態規劃)

題目

在一個由 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;
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章