As Far from Land as Possible

Updated on 19 May, 2025
As Far from Land as Possible header image

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] is 0 or 1

Approach and Intuition

To solve this problem efficiently, consider the steps below:

  1. 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.
  2. 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.
  3. 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.
  4. 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.

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 is 2.
  • 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 of 4. The spread of BFS ensures only the maximum distances are computed and stored as the algorithm progresses.

Solutions

  • C++
  • Java
cpp
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:

  1. 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.
  2. 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).
  3. 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.
java
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:

  1. First, initialize two variables to represent the dimensions (height and width) of the given grid (matrix).

  2. Also, declare a constant INFINITY, set to height + width + 1, which effectively acts as a very high distance value used in the solution.

  3. Begin with a double loop to iterate over each cell in the matrix:

    • If a cell is 1 (land), reset it to 0 denoting the minimum distance from land.
    • If a cell is 0 (water), initialize it to INFINITY. 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.
  4. 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.
  5. Finally, check if maxDistance equals 0 or INFINITY. 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 the maxDistance.

This approach leverages dynamic programming by resolving the shortest possible distance for water cells (0s) from their nearest land cells (1s), 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.

Comments

No comments yet.