最大正方形(maximal-square)——動態規劃

最大正方形(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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章