You are given an N × N matrix in which every cell is colored black or white. Columns are numbered from 0 to N-1 (from left to right). This coloring is represented by a non-empty array of integers A. If the K-th number in the array is equal to X then the X lowest cells in the K-th column of the matrix are black. The rest of the cells in the K-th column are white. The task is to calculate the side length of the biggest black square (a square containing only black cells).
Write a function:
class Solution { public int solution(int[] A); }
that, given an array of integers A of length N representing the coloring of the matrix, returns the side length of the biggest black square.
Examples:
1. Given A = [1, 2, 5, 3, 1, 3], the function should return 2. For example, the black square of side 2 contains the two lowest rows of the 1st and 2nd columns (counting from 0).
2. Given A = [3, 3, 3, 5, 4], the function should return 3. For example, the biggest black square has side 3 and contains the three lowest rows of the last three columns.
3. Given A = [6, 5, 5, 6, 2, 2], the function should return 4. The biggest black square has side 4 and contains the four lowest rows of the first four columns.
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [1..100,000];
- each element of array A is an integer within the range [1..N].
class Solution {
public int solution(int[] A) {
int S[] = new int[A.length];
int Q[] = new int[A.length];
int s = -1;
int m = 1;
for (int i = 0; i < A.length; i++) {
int a = A[i];
if (s == -1) {
s++;
S[s] = a;
Q[s] = 1;
continue;
}
int a0 = S[s];
if (a0 < a) {
s++;
S[s] = a;
Q[s] = 1;
continue;
}
if (a0 == a) {
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
continue;
} else { // drop
if (s == 0) {
S[s] = a; // replace
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
continue;
} else { // a0>a1
while (s > 0) {
int a_1 = S[s - 1];
if (a_1 < a) {
S[s] = a; // replace
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
break;
} else if (a_1 == a) {
Q[s - 1] += Q[s];
Q[s] = 0;
s--;
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
break;
} else { // a_1>a
Q[s - 1] += Q[s];
Q[s] = 0;
s--;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
}
}
if (s == 0) {
if (S[s] > a) {
Q[s]++;
S[s] = a;
} else if (S[s] == a) {
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
} else if (S[s] < a) {
s++;
S[s] = a;
Q[s] = 1;
}
}
}
}
}
while (s > 0) {
Q[s - 1] += Q[s];
s--;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
}
return m;
}
}
class Solution {
public int solution(int[] A) {
int S[] = new int[A.length];
int Q[] = new int[A.length];
int s = -1;
int m = 1;
for (int i = 0; i < A.length; i++) {
int a = A[i];
if (s == -1) {
s++;
S[s] = a;
Q[s] = 1;
continue;
}
int a0 = S[s];
if (a0 < a) {
s++;
S[s] = a;
Q[s] = 1;
continue;
}
if (a0 == a) {
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
continue;
} else { // drop
if (s == 0) {
S[s] = a; // replace
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
continue;
} else { // a0>a1
while (s > 0) {
int a_1 = S[s - 1];
if (a_1 < a) {
S[s] = a; // replace
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
break;
} else if (a_1 == a) {
Q[s - 1] += Q[s];
Q[s] = 0;
s--;
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
break;
} else { // a_1>a
Q[s - 1] += Q[s];
Q[s] = 0;
s--;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
}
}
if (s == 0) {
if (S[s] > a) {
Q[s]++;
S[s] = a;
} else if (S[s] == a) {
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
} else if (S[s] < a) {
s++;
S[s] = a;
Q[s] = 1;
}
}
}
}
}
while (s > 0) {
Q[s - 1] += Q[s];
s--;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
}
return m;
}
}
class Solution {
public int solution(int[] A) {
int S[] = new int[A.length];
int Q[] = new int[A.length];
int s = -1;
int m = 1;
for (int i = 0; i < A.length; i++) {
int a = A[i];
if (s == -1) {
s++;
S[s] = a;
Q[s] = 1;
continue;
}
int a0 = S[s];
if (a0 < a) {
s++;
S[s] = a;
Q[s] = 1;
continue;
}
if (a0 == a) {
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
continue;
} else { // drop
if (s == 0) {
S[s] = a; // replace
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
continue;
} else { // a0>a1
while (s > 0) {
int a_1 = S[s - 1];
if (a_1 < a) {
S[s] = a; // replace
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
break;
} else if (a_1 == a) {
Q[s - 1] += Q[s];
Q[s] = 0;
s--;
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
break;
} else { // a_1>a
Q[s - 1] += Q[s];
Q[s] = 0;
s--;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
}
}
if (s == 0) {
if (S[s] > a) {
Q[s]++;
S[s] = a;
} else if (S[s] == a) {
Q[s]++;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
} else if (S[s] < a) {
s++;
S[s] = a;
Q[s] = 1;
}
}
}
}
}
while (s > 0) {
Q[s - 1] += Q[s];
s--;
if (Q[s] > m && S[s] > m)
m = Q[s] > S[s] ? S[s] : Q[s];
}
return m;
}
}
The solution obtained perfect score.
Tests with the biggest square surrounded by shorter columns. N <= 10.
Tests with alternating small and big numbers (relatively). N <= 15.
Two monotonic sequences or one monotonic and one constant. N <= 75.
Tests with local maximums and local minimums. N <= 75.