Maximal Square from LeetCode

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

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.

  1. 使用二维数组sum[i][j]表示在i行j列原矩阵中包含的1的个数,计算sum可以使用如下的递推式:sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + {1 | 0, matrix[i - 1][j - 1] == 1}; 这个可以在 O (m * n) 时间内完成;

  2. 使用这个二维数组是为了快速计算出(x0, y0) 到 (x1, y1)包含1的数量,当数量等于(x1 - x0) * (y1 - y0)的时候,该矩阵里面包含的全部为1;

  3. 然后可以问这样一个问题,对于给定的边长L,是否有面积为L * L的矩阵存在,这个可以在m * n的时间内完成;而需要检查的边长L,可以使用二分查找的方式计算;这个可以在O(log(maxL) * m * n)时间内完成;


代码如下:

public class Solution {
    public static int maximalSquare(char[][] matrix) {
        int m = matrix.length;
        if (m == 0) {
            return 0;
        }
        int n = matrix[0].length;
        if (n == 0) {
            return 0;
        }
        int[][] sum = new int[m + 1][n + 1];

        sum[1][1] = matrix[0][0] == '1' ? 1 : 0;

        for (int i = 1; i < m + 1; i++) {
            for (int j = 1; j < n + 1; j++) {
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (matrix[i - 1][j - 1] == '1' ? 1 : 0);
            }
        }
        int lb = 0;
        int up = Math.min(m, n) * 2;
        int res = 0;
        while (lb <= up) {
            int mid = (lb + up) / 2;
            if (check(sum, m, n, mid, mid)) {
                res = mid;
                lb = mid + 1;
            } else {
                up = mid - 1;
            }
        }
        return res * res;
    }

    private static boolean check(int[][] sum, int m, int n, int x, int y) {
        for (int i = 0; i + x <= m; i++) {
            for (int j = 0; j + y <= n; j++) {
                int area = sum[i + x][j + y] + sum[i][j] - sum[i + x][j] - sum[i][j + y];
                if (area == x * y) {
                    return true;
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        try (Stream<String> lines = Files.lines(Paths.get("src/main/leetcode/p221/max/square/test.2.txt"))) {
            List<String[]> list = lines.map(str -> str.split("\\s+")).collect(Collectors.toList());
            char[][] matrix = new char[list.size()][list.get(0).length];
            for (int i = 0; i < list.size(); i++) {
                String[] strings = list.get(i);
                for (int j = 0; j < strings.length; j++) {
                    matrix[i][j] = strings[j].charAt(0);
                }
            }
            System.out.println(maximalSquare(matrix));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


你可能感兴趣的:(java,Algorithm)