十:邊界都是1的最大正方形大小

題目

給定一個N×N的矩陣matrix,在這個矩陣中,只有0和1兩種值,返回邊框全是1的最大正方形的邊長長度、
例如
0 1 1 1 1
0 1 0 0 1
0 1 0 0 1
0 1 1 1 1
0 1 0 1 1
其中,邊框全是1的最大正方形的大小爲4 \times 44×4,所以返回4
[要求]
時間複雜度爲O(n^3)O(n
3
),空間複雜度爲O(n^2)O(n
2
)

實現

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[][] m = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                m[i][j] = in.nextInt();
            }
        }
        int res = f(m, n);
        System.out.println(res);
    }
    //枚舉每一個點,然後判斷這個點能否構成正方形
    public static int f(int[][] m, int n) {
        int res = 0;
        int border;
        //原始位置中包含自己在內,右方有多少個連續的1
        int[][] right = right(m, n);
        //原始位置中包含自己在內,下方有多少個連續的1
        int[][] down = down(m, n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (border = Math.min(n - i, n - j); border >= 1; border--) {
                	//利用right、down數組將原來需要驗證是不是正方形的O(N)的操作
                	//替換成了O(1)的操作,空間換時間
                    //驗證是不是正方形
                    //驗證上面的那條邊連續1的個數是否大於等於border
                   boolean up = right[i][j] >= border;
                    //驗證左邊的那條邊連續1的個數是否大於等於border
                    boolean left = down[i][j] >= border;
                    //驗證下面的那條邊連續1的個數是否大於等於border
                    boolean d = right[i + border - 1][j] >= border;
                    //驗證右邊的那條邊連續1的個數是否大於等於border
                    boolean r = down[i][j + border - 1] >= border;
                    if (up && left && d && r) {
                    	res = Math.max(border, res);
                    }
                }
                
            }
        }
        return res;
    }
    
    public static int[][] right(int[][] m, int n) {
        int[][] right = new int[n][n];
        for (int i = n - 1; i >= 0; i--) {
            right[i][n - 1] = m[i][n - 1] == 1 ? 1 : 0;
        }
        for (int i = n - 1; i >= 0; i--) {
            for (int j = n - 2; j >= 0; j--) {
            	right[i][j] += m[i][j] == 0 ? 0 : right[i][j + 1] + 1;
            }
        }
        return right;
    }
    
    public static int[][] down(int[][] m, int n) {
        int[][] down = new int[n][n];
        for (int j = n - 1;j >= 0; j--) {
            down[n - 1][j] = m[n - 1][j] == 1 ? 1 : 0;
        }
        for (int i = n - 2; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                down[i][j] += m[i][j] == 0 ? 0 : down[i + 1][j] + 1;
            }
        }
        return down;
    } 
    
    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();
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章