【预处理数组-最大正方形的边长】
给定一个NN的矩阵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的最大正方形的大小为44,所以返回4.
解答:如何确定一个边框全是1的正方形,确定左上角(i,j),然后以某个边长k遍历,是否四个边都为1。
如何快速的确定四条边上都是1,定义两个二维数组right[i][j] 表示以(i,j) 为顶点的右边,最长有多少个1
down[i][j] 表示(i, j) 为顶点的底下,最长有多少个1。则找最大正方形的边长即以最大边长开始,左上角开始遍历
public class MaxOneBorderSize {
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) {
down[r-1][i] = 1;
right[r-1][i] = right[r-1][i+1] + 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];
int[][] down = new int[m.length][m[0].length];
setBorderMap(m, right, down);
for (int size = Math.min(m.length, m[0].length); size!=0; 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;
}
网友评论