程序员社区

算法-面试题系列(一)??题目五??边框全是1的最大正方形

算法-面试题系列(一)??题目五??边框全是1的最大正方形

给定一个N*N的矩阵matrix,只有0和1两种值,返回边框全是1的最大正方形的边长
长度。
例如:
01111
01001
01001
01111
01011
其中边框全是1的最大正方形的大小为4*4,所以返回4。

算法-面试题系列(一)??题目五??边框全是1的最大正方形插图
image-20210517215559806

算法-面试题系列(一)??题目五??边框全是1的最大正方形插图1
image-20210517215648270

可能会有很多个正方形

一个N*N的矩阵。

长方形数量为 O(N4次方)

算法-面试题系列(一)??题目五??边框全是1的最大正方形插图2
image-20210517220208916

正方形数量为 O(N3次方)

算法-面试题系列(一)??题目五??边框全是1的最大正方形插图3
image-20210517220849994
算法-面试题系列(一)??题目五??边框全是1的最大正方形插图4
image-20210517221709762

优化流程,把确认边长为1的流程,通过预处理数组优化掉

算法-面试题系列(一)??题目五??边框全是1的最大正方形插图5
image-20210517222340729
算法-面试题系列(一)??题目五??边框全是1的最大正方形插图6
image-20210517222716207
算法-面试题系列(一)??题目五??边框全是1的最大正方形插图7
image-20210517222951485
public class Solution {

    public static void setBorderMap(int[][] m, int[][] right, int[][] down) {
        int r = m.length;
        int c = m[0].length;
        if (m[r - 1][c - 1] == 1) {
            right[r - 1][c - 1] = 1;
            down[r - 1][c - 1] = 1;
        }
        for (int i = r - 2; i != -1; i--) {
            if (m[i][c - 1] == 1) {
                right[i][c - 1] = 1;
                down[i][c - 1] = down[i + 1][c - 1] + 1;
            }
        }
        for (int i = c - 2; i != -1; i--) {
            if (m[r - 1][i] == 1) {
                right[r - 1][i] = right[r - 1][i + 1] + 1;
                down[r - 1][i] = 1;
            }
        }
        for (int i = r - 2; i != -1; i--) {
            for (int j = c - 2; j != -1; j--) {
                if (m[i][j] == 1) {
                    right[i][j] = right[i][j + 1] + 1;
                    down[i][j] = down[i + 1][j] + 1;
                }
            }
        }
    }

    public static int getMaxSize(int[][] m) {
        int[][] right = new int[m.length][m[0].length];//预处理数组right
        int[][] down = new int[m.length][m[0].length];//预处理数组down
        setBorderMap(m, right, down); // O(N^2); + //生成预处理数组
        
        for (int size = Math.min(m.length, m[0].length); size != 0; size--) {//正方形边长 size--
            if (hasSizeOfBorder(size, right, down)) {
                return size;
            }
        }
        return 0;
    }

    public static boolean hasSizeOfBorder(int size, int[][] right, int[][] down) {
        for (int i = 0; i != right.length - size + 1; i++) {
            for (int j = 0; j != right[0].length - size + 1; j++) {
                if (right[i][j] >= size && down[i][j] >= size
                        && right[i + size - 1][j] >= size
                        && down[i][j + size - 1] >= size) {
                    return true;
                }
            }
        }
        return false;
    }
    
    public static int[][] generateRandom01Matrix(int rowSize, int colSize) {
        int[][] res = new int[rowSize][colSize];
        for (int i = 0; i != rowSize; i++) {
            for (int j = 0; j != colSize; j++) {
                res[i][j] = (int) (Math.random() * 2);
            }
        }
        return res;
    }

    public static void printMatrix(int[][] matrix) {
        for (int i = 0; i != matrix.length; i++) {
            for (int j = 0; j != matrix[0].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        int[][] matrix = generateRandom01Matrix(7, 8);
        printMatrix(matrix);
        System.out.println(getMaxSize(matrix));
    }
}
赞(0) 打赏
未经允许不得转载:IDEA激活码 » 算法-面试题系列(一)??题目五??边框全是1的最大正方形

一个分享Java & Python知识的社区