Maximal Square

Question

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area.

Example

For example, given the following matrix:

1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0

Return 4.

Solution

正方形可以一用一个角加边长来确定。遍历数组,以数组元素为正方形右下角,求出最大边长即可求出最大面积。

状态:square[i][j]代表以matrix[i-1][j-1]为右下角的正方形最长的边长。

转移函数:

    1. square[i][j]=min(square[i-1][j], square[i-1][j-1], square[i][j-1])+1 
    (matrix[i-1][j-1] == 1)

    2. square[i][j]=0 (matrix[i-1][j-1] == 0)

    每个正方形的左边,上面,左上正方形最大边长决定了该正方形的最大边长

初始化:额外多创建一行和一列,并初始化为0

结果:遍历过程中每次取最大边长之积

tips: 因为每个正方形只和其左边,上面,左上正方形有关,因此可以用rolling array来进行空间优化,只用两行来记录即可,更新偶数行看奇数行,更新奇数行看偶数行。

代码如下:

public class Solution {
    /**
     * @param matrix: a matrix of 0 and 1
     * @return: an integer
     */
    public int maxSquare(int[][] matrix) {
        // write your code here
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return 0;
        }
        int m = matrix.length;
        int n = matrix[0].length;
        //使用rolling array
        int[][] square = new int[2][n + 1];

        for(int i = 0; i < 2; i++){
            square[i][0] = 0;
        }

        for(int j = 0; j <= n; j++){
            square[0][j] = 0;
        }

        int max = 0;
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                if(matrix[i - 1][j - 1] == 1){
                    square[i % 2][j] = Math.min(square[i % 2][j - 1], Math.min(square[(i - 1) % 2][j - 1], square[(i - 1) % 2][j])) + 1;
                }else{
                    square[i % 2][j] = 0;
                }
                max = Math.max(max, square[i % 2][j] * square[i % 2][j]);
            }
        }

        return max;
    }
}

results matching ""

    No results matching ""