Reputation: 21445
I have an array of size m rows n columns with each cell size is considered as 1x1.
Now I am removing a list of rows and columns from this array, next I want to know the biggest gap that can be formed after removing them.
Example:
Array of size 4 rows and 3 columns, now I am removing rows {1,2,3} and columns {1,2}
This results is an array having biggest gap of 12 cells.
Another Example:
Array of size 4 rows and 4 columns, now I am removing rows {2} and columns {2}
This results is an array having biggest gap of 4 cells.
I have come up with below code that works for this example:
static long process(int n, int m, int[] h, int[] v) {
ArrayList<ArrayList<Long>> array = new ArrayList<ArrayList<Long>>();
for (int r = 0; r <= n; r++) {
ArrayList<Long> temp = new ArrayList<Long>();
for (int c = 0; c <= m; c++) {
temp.add((long) 1);
}
array.add(temp);
}
int[] x = h;
int xnum = x.length;
Arrays.sort(x);
int[] y = v;
int ynum = y.length;
Arrays.sort(y);
// removing bar i means that list at i-1 and at i
for (int a = xnum - 1; a >= 0; a--) {
int i = x[a];
for (int cell = 0; cell < array.get(i).size(); cell++) {
array.get(i).set(cell, array.get(i).get(cell) + array.get(i - 1).get(cell));
}
array.remove(i - 1);
}
ArrayList<ArrayList<Long>> newarray = new ArrayList<ArrayList<Long>>();
for (int col = 0; col < array.get(0).size(); col++) {
ArrayList<Long> temp = new ArrayList<Long>();
for (int row = 0; row < array.size(); row++) {
temp.add(array.get(row).get(col));
}
newarray.add(temp);
}
for (int b = ynum - 1; b >= 0; b--) {
int i = y[b];
for (int cell = 0; cell < newarray.get(i).size(); cell++) {
newarray.get(i).set(cell, newarray.get(i).get(cell) + newarray.get(i - 1).get(cell));
}
newarray.remove(i - 1);
}
long max = 1;
for (ArrayList<Long> arr : newarray) {
for (long num : arr) {
if (num > max)
max = num;
}
}
return max;
}
How can we reduce the time complexity of this code, because the size of rows and columns is:
1 <= rows, columns <= 100000
Upvotes: 0
Views: 576
Reputation: 24229
Let's start by looking at your current solution, by using simple array instead of ArrayList we can reduce this code to:
static long process(int rows, int cols, int[] hor, int[] ver) {
final long[][] a = new long[rows][cols];
for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) a[i][j] = 1;
for (int h : hor) for (int j = 0; j < cols; j++) a[h - 1][j] = a[h][j] = a[h - 1][j] + a[h][j];
for (int v : ver) for (int i = 0; i < rows; i++) a[i][v - 1] = a[i][v] = a[i][v - 1] + a[i][v];
long max = 0;
for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) max = Math.max(max, a[i][j]);
return max;
}
this code has complexity O(N^2)
but, we should understand that biggest gap will be in place where biggest count of consecutive rows and columns are removed, thus we can simplify algorithm to:
static int maxConsecutive(int[] a) {
Arrays.sort(a);
int max = 0;
int start = 0;
for (int i = 0; i < a.length; i++)
if (a[i] - a[start] == i - start) max = Math.max(max, i - start + 1);
else start = i;
return max;
}
static long process(int rows, int cols, int[] hor, int[] ver) {
long maxH = maxConsecutive(hor);
long maxV = maxConsecutive(ver);
return (maxH + 1) * (maxV + 1);
}
which has complexity O(logN)
Upvotes: 2