
Problem Statement
In the provided problem, the task is to evaluate an n x n
grid, filled with 0s
representing water and 1s
representing land. The challenge is to identify a water cell from which the distance to the nearest land cell is the greatest possible. This distance is calculated based on the Manhattan distance formula, where dist((x0, y0), (x1, y1)) = |x0 - x1| + |y0 - y1|
. If the entire grid is composed of land or entirely of water, the function should return -1
.
Examples
Example 1
Input:
grid = [[1,0,1],[0,0,0],[1,0,1]]
Output:
2
Explanation:
The cell (1, 1) is as far as possible from all the land with distance 2.
Example 2
Input:
grid = [[1,0,0],[0,0,0],[0,0,0]]
Output:
4
Explanation:
The cell (2, 2) is as far as possible from all the land with distance 4.
Constraints
n == grid.length
n == grid[i].length
1 <= n <= 100
grid[i][j]
is0
or1
Approach and Intuition
To solve this problem efficiently, consider the steps below:
Initiate a breadth-first search (BFS) starting from all the land cells in the grid.
- Use a queue data structure to facilitate the level-order traversal necessary for BFS.
- Push all land cells onto the queue initially and mark them with a unique identifier to prevent revisit, effectively treating the grid as its own visited array by changing
1s
to a marker value.
Explore all neighboring cells iteratively.
- Dequeue from the front adding all unvisited
0
(water) cells to the queue. - For each water cell accessed, calculate its distance from the nearest land cell based on the Manhattan distance from the cell it was reached from (+1 distance from the previous cell).
- Replace the value
0
in this water cell with the calculated distance to avoid revisiting and to store the maximum distance found so far.
- Dequeue from the front adding all unvisited
After BFS completes, the answer is the maximum distance found in any water cell.
- Iterate through the grid to find this maximum once the BFS is exhausted and all accessible cells have been visited.
Special cases to handle:
- If no water is present (i.e., the initial BFS queue is empty as no
1
was pushed), output-1
. - Similarly, if no
1
(land) is placed and all are water (0
), BFS would not start correctly, output-1
.
- If no water is present (i.e., the initial BFS queue is empty as no
Let’s review this with the examples:
- In the First Example, multiple land cells surround a large body of water. The maximum distance achieved from a land cell to a water cell is at
(1,1)
where the distance is2
. - In the Second Example, there is a periphery of land on one edge, and the furthest possible water cell from this land is at
(2,2)
, resulting in a maximum distance of4
. The spread of BFS ensures only the maximum distances are computed and stored as the algorithm progresses.
Solutions
- C++
- Java
class Solution {
public:
int calculateMaxDistance(vector<vector<int>>& matrix) {
int nrows = matrix.size();
int ncols = matrix[0].size();
const int MAX_DIST = nrows + ncols + 1;
for (int r = 0; r < nrows; r++) {
for (int c = 0; c < ncols; c++) {
if (matrix[r][c]) {
matrix[r][c] = 0;
} else {
matrix[r][c] = MAX_DIST;
matrix[r][c] = min(matrix[r][c], min(r > 0 ? matrix[r - 1][c] + 1 : MAX_DIST,
c > 0 ? matrix[r][c - 1] + 1 : MAX_DIST));
}
}
}
int finalMax = INT_MIN;
for (int r = nrows - 1; r >= 0; r--) {
for (int c = ncols - 1; c >= 0; c--) {
matrix[r][c] = min(matrix[r][c], min(r < nrows - 1 ? matrix[r + 1][c] + 1 : MAX_DIST,
c < ncols - 1 ? matrix[r][c + 1] + 1 : MAX_DIST));
finalMax = max(finalMax, matrix[r][c]);
}
}
return finalMax == 0 || finalMax == MAX_DIST ? -1 : finalMax;
}
};
The task "As Far from Land as Possible" involves finding the maximum distance to the nearest land from any cell in a matrix that contains both land (represented by 1s
) and water (represented by 0s
). This solution is implemented in C++.
The approach taken involves two sweeps of the matrix:
- Firstly, initialize a new matrix or modify the existing one where all land positions are set to
0
and all water positions to a very high value indicating they are initially inaccessible. - In the first sweep (top-left to bottom-right), update every water cell with the minimum distance to land looking upwards (from the above row) and leftwards (from the previous column).
- In the second sweep (bottom-right to top-left), perform a similar update but this time looking downwards and rightwards.
Throughout the process, keep updating the value of each cell to ensure it holds the minimum value calculated from all possible directions. After completing both sweeps, the maximum value within the matrix, which represents water, is identified as the largest distance from any cell to land.
The function also solves edge cases where updating the matrix might go out of bounds — these are handled with conditionals that check the range of indices in the matrix and a precomputed MAX_DIST value to manage unreachable conditions.
Finally, after both sweeps, the matrix is checked for the maximum distance. If the maximum value remains unchanged from its initialized MAX_DIST
or is 0
, this would indicate no valid answer (-1), else it returns the maximum distance found.
Thus, the solution ensures:
- Performance is manageable with a two-pass O(n*m) algorithm where n, m are the dimensions of the matrix.
- Edge cases for small matrices or edge placements are correctly handled.
class Solution {
public int maximumDistance(int[][] matrix) {
int height = matrix.length;
int width = matrix[0].length;
final int INFINITY = height + width + 1;
// Traverse from top-left to bottom-right
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c++) {
if (matrix[r][c] == 1) {
matrix[r][c] = 0;
} else {
matrix[r][c] = INFINITY;
matrix[r][c] = Math.min(matrix[r][c],
Math.min(r > 0 ? matrix[r - 1][c] + 1 : INFINITY,
c > 0 ? matrix[r][c - 1] + 1 : INFINITY));
}
}
}
// Traverse from bottom-right to top-left
int maxDistance = Integer.MIN_VALUE;
for (int r = height - 1; r >= 0; r--) {
for (int c = width - 1; c >= 0; c--) {
matrix[r][c] = Math.min(matrix[r][c],
Math.min(r < height - 1 ? matrix[r + 1][c] + 1 : INFINITY,
c < width - 1 ? matrix[r][c + 1] + 1 : INFINITY));
maxDistance = Math.max(maxDistance, matrix[r][c]);
}
}
return maxDistance == 0 || maxDistance == INFINITY ? -1 : maxDistance;
}
};
To solve the "As Far from Land as Possible" problem, follow these steps using Java:
First, initialize two variables to represent the dimensions (
height
andwidth
) of the given grid (matrix
).Also, declare a constant
INFINITY
, set toheight + width + 1
, which effectively acts as a very high distance value used in the solution.Begin with a double loop to iterate over each cell in the matrix:
- If a cell is
1
(land), reset it to0
denoting the minimum distance from land. - If a cell is
0
(water), initialize it toINFINITY
. Update the cell value to be the minimum between its current value and the results of checks in four potential directions (left and top), making sure to add 1 to account for the distance increment.
- If a cell is
Implement a second double loop to iterate over the matrix, starting from the bottom-right corner and moving to the top-left:
- For each cell, compare and set the value to be the minimum between its current value and the results from the bottom and right cells, once again, adding 1 to count the distance.
- Concurrently, update the
maxDistance
variable to store the maximum distance found from a water cell to land.
Finally, check if
maxDistance
equals0
orINFINITY
. If it does, return-1
, as this would mean all cells are land, or water cells are too far from any land respectively. If not, return themaxDistance
.
This approach leverages dynamic programming by resolving the shortest possible distance for water cells (0
s) from their nearest land cells (1
s), considering optimal substructures in matrix traversal both from top-left to bottom-right and bottom-right to top-left. This method ensures that each cell's value is the minimum distance to the nearest land, thereby facilitating the extraction of the maximum distance for any water cell effectively.
No comments yet.