Maximum of all distances to the nearest 1 cell from any 0 cell in a Binary matrix

Given a Matrix of size N*N filled with 1‘s and 0‘s, the task is to find the maximum distance from a 0-cell to its nearest 1-cell. If the matrix is filled with only 0’s or only 1’s, return -1.

Note: Only horizontal and vertical movements are allowed in the matrix.

Examples:



Input: 
mat[][] = {{0, 1, 0},
           {0, 0, 1},
           {0, 0, 0}}
Output: 3
Explanation: 
Cell number (2, 0) is at the farthest
distance of 3 cells from both the
1-cells (0, 1) and (1, 2).

Input: 
mat[][] = {{1, 0, 0},
           {0, 0, 0},
           {0, 0, 0}}
Output: 4
Explanation: 
Cell number (2, 2) is at the farthest 
distance of 4 cells from the only 
1-cell (1, 1).

Approach 1: Naive Approach
For each 0-cell, compute its distance from every 1-cell and store the minimum. The maximum of all those minimal distances is the answer.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find the maximum
// distance from a 0-cell to a 1-cell
  
#include <bits/stdc++.h>
using namespace std;
  
int maxDistance(vector<vector<int> >& grid)
{
    vector<pair<int, int> > one;
  
    int M = grid.size();
    int N = grid[0].size();
    int ans = -1;
  
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
            if (grid[i][j] == 1)
                one.emplace_back(i, j);
        }
    }
  
    // If the matrix consists of only 0's
    // or only 1's
    if (one.empty() || M * N == one.size())
        return -1;
  
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
  
            if (grid[i][j] == 1)
                continue;
  
            // If it's a 0-cell
            int dist = INT_MAX;
            for (auto& p : one) {
  
                // calculate its distance
                // with every 1-cell
                int d = abs(p.first - i)
                        + abs(p.second - j);
  
                // Compare and store the minimum
                dist = min(dist, d);
  
                if (dist <= ans)
                    break;
            }
  
            // Compare ans store the maximum
            ans = max(ans, dist);
        }
    }
    return ans;
}
  
// Driver code
int main()
{
    vector<vector<int> > arr
        = { { 0, 0, 1 },
            { 0, 0, 0 },
            { 0, 0, 0 } };
  
    cout << maxDistance(arr) << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to find the maximum
// distance from a 0-cell to a 1-cell
   
  
import java.util.*;
  
class GFG{
      
static class pair
    int first, second; 
    public pair(int first, int second)  
    
        this.first = first; 
        this.second = second; 
    }    
}  
static int maxDistance(int [][]grid)
{
    Vector<pair> one = new Vector<pair>();
   
    int M = grid.length;
    int N = grid[0].length;
    int ans = -1;
   
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
            if (grid[i][j] == 1)
                one.add(new pair(i, j));
        }
    }
   
    // If the matrix consists of only 0's
    // or only 1's
    if (one.isEmpty() || M * N == one.size())
        return -1;
   
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
   
            if (grid[i][j] == 1)
                continue;
   
            // If it's a 0-cell
            int dist = Integer.MAX_VALUE;
            for (pair p : one) {
   
                // calculate its distance
                // with every 1-cell
                int d = Math.abs(p.first - i)
                        + Math.abs(p.second - j);
   
                // Compare and store the minimum
                dist = Math.min(dist, d);
   
                if (dist <= ans)
                    break;
            }
   
            // Compare ans store the maximum
            ans = Math.max(ans, dist);
        }
    }
    return ans;
}
   
// Driver code
public static void main(String[] args)
{
    int [][]arr
        = { { 0, 0, 1 },
            { 0, 0, 0 },
            { 0, 0, 0 } };
   
    System.out.print(maxDistance(arr) +"\n");
}
}
  
// This code contributed by Princi Singh

chevron_right


Output:

4

Time complexity: O(M*N*P) where grid is of size M*N and P is the count of 1-cells.
Auxiliary Space: O(P)

Approach 2: Using BFS
Start from a 1-cell, and perform a Breadth First Search traversal, layer by layer. The maximum layer, upto which we can retrieve, is our answer.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find the maximum
// distance from a 0-cell to a 1-cell
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the maximum distance
int maxDistance(vector<vector<int> >& grid)
{
    // Queue to store all 1-cells
    queue<pair<int, int> > q;
  
    // Grid dimensions
    int M = grid.size();
    int N = grid[0].size();
    int ans = -1;
  
    // Directions traversable from
    // a given a particular cell
    int dirs[4][2] = { { 0, 1 },
                       { 1, 0 },
                       { 0, -1 },
                       { -1, 0 } };
  
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
            if (grid[i][j] == 1)
                q.emplace(i, j);
        }
    }
  
    // If the grid contains
    // only 0s or only 1s
    if (q.empty() || M * N == q.size())
        return -1;
  
    while (q.size()) {
  
        int cnt = q.size();
  
        while (cnt--) {
  
            // Access every 1-cell
            auto p = q.front();
            q.pop();
  
            // Traverse all possible
            // directions from the cells
            for (auto& dir : dirs) {
  
                int x = p.first + dir[0];
                int y = p.second + dir[1];
  
                // Check if the cell is
                // within the boundaries
                // or contains a 1
                if (x < 0 || x >= M
                    || y < 0 || y >= N
                    || grid[x][y])
                    continue;
  
                q.emplace(x, y);
                grid[x][y] = 1;
            }
        }
        ++ans;
    }
    return ans;
}
  
// Driver code
int main()
{
    vector<vector<int> > arr = { { 0, 0, 1 },
                                 { 0, 0, 0 },
                                 { 0, 0, 1 } };
  
    cout << maxDistance(arr) << endl;
    return 0;
}

chevron_right


Output:

3

Time complexity: O(M*N)
Auxiliary Space: O(M*N)

Approach 3: Using Dynamic Programming

  • Keep updating the matrix of the maximum distances that have been traveled.
  • Traverse from the top left hand cell (0, 0) of the matrix to the bottom right. Let grid[i][j] represent maximum distance from the nearest 1-cell on the left or above(or of course on itself).
  • Do a second pass from bottom right to top left, updating the grid array, defining the cell grid[i][j] as the minimum of grid[i][j], grid[i+1][j], and grid[i][j+1].
  • Keep track of the maximum value during the bottom right to top left traversal and return the value at the end.In case the value is 0, i.e the grid is filled with only 0’s or only 1’s, return -1.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find the maximum
// distance from a 0-cell to a 1-cell
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the maximum distance
int maxDistance(vector<vector<int> >& grid)
{
    if (!grid.size())
        return -1;
    int N = grid.size();
  
    int INF = 1000000;
  
    // DP matrix
    vector<vector<int> >
    dp(N, vector<int>(N, 0));
  
    grid[0][0] = grid[0][0] == 1
                     ? 0
                     : INF;
  
    // Set up top row and left column
    for (int i = 1; i < N; i++)
        grid[0][i] = grid[0][i] == 1
                         ? 0
                         : grid[0][i - 1] + 1;
    for (int i = 1; i < N; i++)
        grid[i][0] = grid[i][0] == 1
                         ? 0
                         : grid[i - 1][0] + 1;
  
    // Pass one: top left to bottom right
    for (int i = 1; i < N; i++) {
        for (int j = 1; j < N; j++) {
            grid[i][j] = grid[i][j] == 1
                             ? 0
                             : min(grid[i - 1][j],
                                   grid[i][j - 1])
                                   + 1;
        }
    }
  
    // Check if there was no "One" Cell
    if (grid[N - 1][N - 1] >= INF)
        return -1;
  
    // Set up top row and left column
    int maxi = grid[N - 1][N - 1];
    for (int i = N - 2; i >= 0; i--) {
        grid[N - 1][i]
            = min(grid[N - 1][i],
                  grid[N - 1][i + 1] + 1);
        maxi = max(grid[N - 1][i], maxi);
    }
  
    for (int i = N - 2; i >= 0; i--) {
        grid[i][N - 1]
            = min(grid[i][N - 1],
                  grid[i + 1][N - 1] + 1);
        maxi = max(grid[i][N - 1], maxi);
    }
  
    // Past two: bottom right to top left
    for (int i = N - 2; i >= 0; i--) {
        for (int j = N - 2; j >= 0; j--) {
            grid[i][j] = min(grid[i][j],
                             min(grid[i + 1][j] + 1,
                                 grid[i][j + 1] + 1));
            maxi = max(grid[i][j], maxi);
        }
    }
  
    return !maxi ? -1 : maxi;
}
  
// Driver code
int main()
{
    vector<vector<int> > arr = { { 0, 0, 1 },
                                 { 0, 0, 0 },
                                 { 0, 0, 0 } };
  
    cout << maxDistance(arr) << endl;
    return 0;
}

chevron_right


Output:

3

Time complexity: O(M*N)
Auxiliary Space: O(1)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : princi singh