2.2 Longest Cross of 1s in binary matrix
Assumption: Given matrix is not null, size of n * m, n & m >= 0
Input: int[][] matrix with matrix.length = n, matrix[0].length = m
Output: int the arm length of the longest cross
Solution:
Maintain four directions to store the longest consecutive 1s (as in 1.1)
Find the min among the four directions
dp[i][j] = min(dp1, dp2, dp3, dp4)
left -> right dp1[n][m]
0 1 0 0 matrix[i][j] == 1, dp[i][j] = dp[i][j - 1] + 1
1 2 3 4 refer to left
0 1 0 0
0 1 0 0
right - > left dp2[n][m]
0 1 0 0 matrix[i][j] == 1, dp[i][j] = dp[i][j + 1] + 1
4 3 2 1 refer to right
0 1 0 0
0 1 0 0
up -> down M3[n][m]
0 1 0 0 matrix[i][j] == 1, dp[i][j] = dp[i - 1][j] + 1
1 2 1 1 refer to top
0 3 0 0
0 4 0 0
down -> up M4[n][m]
0 4 0 0 matrix[i][j] == 1, dp[i][j] = dp[i + 1][j] + 1
1 3 1 1 refer to bottom
0 2 0 0
0 1 0 0
TC: 4 for loops 4*n*m + get min n*m = O(n*m)
SC: Merge 4 into 2 int[][], = O(n*m)
public int largest(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
if (n == 0 || m == 0) { return 0; }
// maintain 2 int[][]
int[][] leftUp = leftUp(matrix, n, m);
int[][] rightDown = rightDown(matrix, n, m);
return merge(leftUp, rightDown, n, m);
}
private int[][] leftUp(int[][] matrix, int n, int m) {
int[][] left = new int[n][m];
int[][] up = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// initialize
if (matrix[i][j] == 1) {
if (i = 0 && j = 0) {
up[i][j] = 1;
left[i][j] = 1;
} else if (i == 0) { // top row
up[i][j] = 1;
left[i][j] = left[i][j - 1] + 1;
} else if (j == 0) { // left column
up[i][j] = up[i - 1][j] + 1;
left[i][j] = 1;
} else {
up[i][j] = up[i - 1][j] + 1;
left[i][j] - left[i][j - 1] + 1;
}
}
}
}
merge(left, up, n, m);
return left;
}
private int[][] rightDown (int[][] matrix, int n, int m) {
int[][] right = new int[n][m];
int[][] down = new int[n][m];
for (int i = n - 1; i >= 0; i--) {
for (int j = m - 1; j >= 0; j--) {
if (matrix[i][j] == 1) {
if (i = n - 1 && j = m - 1) {
right[i][j] = 1;
down[i][j] = 1;
} else if (i = n - 1) { // bottom row
right[i][j] = right[i][j + 1] + 1;
down[i][j] = 1;
} else if (j = m - 1) { // right column
right[i][j] = 1;
down[i][j] = down[i + 1][j] + 1;
} else {
right[i][j] = right[i][j + 1] + 1;
down[i]i[j] = down[i + 1][j];
}
}
}
}
merge(right, down, n, m);
return right;
}
private int merge (int[][] leftUp, int[][] rightDown, int n, int m) {
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
leftUp[i][j] = Math.min(leftUp[i][j], rightDown[i][j]);
res = Math.max(leftUp[i][j], res);
}
}
return res;
}
Last updated
Was this helpful?