71 lines
1.8 KiB
Java
71 lines
1.8 KiB
Java
|
import java.util.*;
|
||
|
|
||
|
public class MaximumZeroSubmatrix {
|
||
|
|
||
|
public static int maximumZeroSubmatrix(int[][] a) {
|
||
|
int R = a.length;
|
||
|
int C = a[0].length;
|
||
|
|
||
|
int res = 0;
|
||
|
int[] d = new int[C];
|
||
|
Arrays.fill(d, -1);
|
||
|
int[] d1 = new int[C];
|
||
|
int[] d2 = new int[C];
|
||
|
int[] st = new int[C];
|
||
|
for (int r = 0; r < R; ++r) {
|
||
|
for (int c = 0; c < C; ++c)
|
||
|
if (a[r][c] == 1)
|
||
|
d[c] = r;
|
||
|
int size = 0;
|
||
|
for (int c = 0; c < C; ++c) {
|
||
|
while (size > 0 && d[st[size - 1]] <= d[c]) --size;
|
||
|
d1[c] = size == 0 ? -1 : st[size - 1];
|
||
|
st[size++] = c;
|
||
|
}
|
||
|
size = 0;
|
||
|
for (int c = C - 1; c >= 0; --c) {
|
||
|
while (size > 0 && d[st[size - 1]] <= d[c]) --size;
|
||
|
d2[c] = size == 0 ? C : st[size - 1];
|
||
|
st[size++] = c;
|
||
|
}
|
||
|
for (int j = 0; j < C; ++j)
|
||
|
res = Math.max(res, (r - d[j]) * (d2[j] - d1[j] - 1));
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
// random test
|
||
|
public static void main(String[] args) {
|
||
|
Random rnd = new Random(1);
|
||
|
for (int step = 0; step < 1000; step++) {
|
||
|
int R = rnd.nextInt(10) + 1;
|
||
|
int C = rnd.nextInt(10) + 1;
|
||
|
int[][] a = new int[R][C];
|
||
|
for (int r = 0; r < R; r++)
|
||
|
for (int c = 0; c < C; c++)
|
||
|
a[r][c] = rnd.nextInt(2);
|
||
|
int res1 = maximumZeroSubmatrix(a);
|
||
|
int res2 = slowMaximumZeroSubmatrix(a);
|
||
|
if (res1 != res2)
|
||
|
throw new RuntimeException(res1 + " " + res2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int slowMaximumZeroSubmatrix(int[][] a) {
|
||
|
int res = 0;
|
||
|
int R = a.length;
|
||
|
int C = a[0].length;
|
||
|
for (int r2 = 0; r2 < R; r2++)
|
||
|
for (int c2 = 0; c2 < C; c2++)
|
||
|
for (int r1 = 0; r1 <= r2; r1++)
|
||
|
m1:for (int c1 = 0; c1 <= c2; c1++) {
|
||
|
for (int r = r1; r <= r2; r++)
|
||
|
for (int c = c1; c <= c2; c++)
|
||
|
if (a[r][c] != 0)
|
||
|
continue m1;
|
||
|
res = Math.max(res, (r2 - r1 + 1) * (c2 - c1 + 1));
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
}
|