Open In App

Nearest 1 in a binary matrix

Last Updated : 11 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary matrix of order m*n, the task is to find the distance of the nearest 1 for each 0 in the matrix and print the final distance matrix. From any cell (i,j), we can move only in four directions up, down, left and right. 
Note: Distance from one cell to immediate another cell is always incremented by 1.

Examples: 

Input : m = 3, n = 4
        mat[m][n] = {{0, 0, 0, 1},
                     {0, 0, 1, 1},
                     {0, 1, 1, 0}}
Output: 3 2 1 0
        2 1 0 0
        1 0 0 1

A simple brute force solution for this problem is to for each 0 in the matrix, recursively call either DFS or BFS function to check the nearest 1 in the matrix.

Here we are using the dfs approach to calculate the distance of nearest ‘1’.

Implementation: Following is the implementation of above algorithm.

C++




#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000;
   
// distance matrix which stores the distance of
// nearest '1'
int dist[MAX][MAX];
  
int dfs(int mat[][MAX], int m, int n,int i,int j,vector<vector<bool>> visited)
    // here we are validating if current coordinate is
    // out of bound or already visited or not
    if(i<0||j<0||i>=m||j>=n||visited[i][j]==true)
     return MAX;
       
     //we reach the cell having 1 so, return 
     if(mat[i][j]==1)  return 0;
       
     //otherwise first mark current coordinate visited
     visited[i][j]=true;
       
     // checking using dfs in all four direction to get min for the 
     // nearest 1 +1 for the current cell
     int val=1+min(dfs(mat,m,n,i+1,j,visited),min(dfs(mat,m,n,i-1,j,visited),
                min(dfs(mat,m,n,i,j+1,visited),dfs(mat,m,n,i,j-1,visited))));
                    
     //backtrack so that other path when reach can use this cell               
    visited[i][j]=false;
    return val;
                           
}
  
// Function to find the nearest '1'
void nearestOne(int mat[][MAX], int m, int n)
{
    vector<vector<bool>> visited(m,vector<bool>(n,false));
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(mat[i][j]==0)
               dist[i][j]=dfs(mat,m,n,i,j,visited);
        }
    }
    return;
}
  
  
int main()
{
    int m = 3, n = 4;
    int mat[][MAX] = {{0, 0, 0, 1},
        {0, 0, 1, 1},
        {0, 1, 1, 0}
    };
    
    // Fills values in dist[][]
    nearestOne(mat, m, n);
   
    // print distance matrix
    for (int i=0; i<m; i++)
    {
        for (int j=0; j<n; j++)
            cout << dist[i][j] << " ";
        cout << endl;
    }
    return 0;
}


Java




/*package whatever //do not write package name here */
  
import java.io.*;
  
class GFG {
        static int MAX = 1000;
       
    // distance matrix which stores the distance of
    // nearest '1'
    static int dist[][] = new int[MAX][MAX];
      
    static int dfs(int mat[][], int m, int n,int i,int j,boolean visited[][])
    
        //here we are validating if current 
      // coordinate is out of bound or already visited or not
        if(i < 0 || j < 0 || i >= m || 
           j >= n || visited[i][j] == true)
         return MAX;
           
         //we reach the cell having 1 so, return 
         if(mat[i][j] == 1return 0;
           
         //otherwise first mark current coordinate visited
         visited[i][j] = true;
           
         //checking using dfs in all four direction 
      // to get min for the nearest 1 +1 for the current cell
         int val=1+Math.min(dfs(mat, m, n, i + 1, j, visited), 
                            Math.min(dfs(mat, m, n, i - 1, j, visited),
                    Math.min(dfs(mat, m, n, i, j + 1, visited), 
                             dfs(mat, m, n, i, j - 1, visited))));
                        
         //backtrack so that other path when reach can use this cell               
        visited[i][j] = false;
        return val;
                               
    }
      
    // Function to find the nearest '1'
    static void nearestOne(int mat[][], int m, int n)
    {
        boolean visited[][] = new boolean[m][n];
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                visited[i][j] = false;
            }
        }
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(mat[i][j] == 0)
                   dist[i][j] = dfs(mat, m, n, i, j, visited);
            }
        }
        return;
    }
      
// Driver Code
public static void main(String args[])
{
    int m = 3, n = 4;
    int mat[][] = {{0, 0, 0, 1},
        {0, 0, 1, 1},
        {0, 1, 1, 0}
    };
        
    // Fills values in dist[][]
    nearestOne(mat, m, n);
       
    // print distance matrix
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
            System.out.print(dist[i][j] + " ");
        System.out.println();
    }
}
}
  
// This code is contributed by shinjanpatra


Python3




MAX = 1000;
def dfs(mat,  m,  n, i, j, visited):
   
    # here we are validating if current coordinate is
    # out of bound or already visited or not
    if(i < 0 or j < 0 or i >= m or j >= n or  visited[i][j] == True):
        return MAX;
       
    # we reach the cell having 1 so, return 
    if(mat[i][j] == 1):
        return 0;
       
    # otherwise first mark current coordinate visited
    visited[i][j] = True;
       
    # checking using dfs in all four direction to get min for the 
    # nearest 1 +1 for the current cell
    val=1+min(dfs(mat,m,n,i+1,j,visited),min(dfs(mat,m,n,i-1,j,visited), min(dfs(mat,m,n,i,j+1,visited),dfs(mat,m,n,i,j-1,visited))));
                    
    # backtrack so that other path when reach can use this cell               
    visited[i][j] = False;
    return val;
                           
# Function to find the nearest '1'
def nearestOne(mat,  m,  n,dist):
  
    visited =  [[False] * n for _ in range(m)]
      
    for i in range(m):
        for j in range(n):
            if(mat[i][j] == 0):
               dist[i][j]=dfs(mat,m,n,i,j,visited);
      
    return;
  
m = 3
n = 4;
mat = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 0]];
  
# distance matrix which stores the distance of
# nearest '1'
dist =  [[0] * n for _ in range(m)]
      
# Fills values in dist[][]
nearestOne(mat, m, n,dist);
      
# print distance matrix
print(dist);
     
# This code is contributed by phasing17.


C#




using System;
using System.Collections.Generic;
  
class GFG {
        static int MAX = 1000;
       
    // distance matrix which stores the distance of
    // nearest '1'
    static int[, ] dist = new int[MAX, MAX];
      
    static int dfs(int[, ] mat, int m, int n,int i,int j, bool[, ] visited)
    
        //here we are validating if current 
      // coordinate is out of bound or already visited or not
        if(i < 0 || j < 0 || i >= m || 
           j >= n || visited[i, j] == true)
         return MAX;
           
         //we reach the cell having 1 so, return 
         if(mat[i, j] == 1)  return 0;
           
         //otherwise first mark current coordinate visited
         visited[i, j] = true;
           
         //checking using dfs in all four direction 
      // to get min for the nearest 1 +1 for the current cell
         int val=1+Math.Min(dfs(mat, m, n, i + 1, j, visited), 
                            Math.Min(dfs(mat, m, n, i - 1, j, visited),
                    Math.Min(dfs(mat, m, n, i, j + 1, visited), 
                             dfs(mat, m, n, i, j - 1, visited))));
                        
         //backtrack so that other path when reach can use this cell               
        visited[i, j] = false;
        return val;
                               
    }
      
    // Function to find the nearest '1'
    static void nearestOne(int[,] mat, int m, int n)
    {
        bool[,] visited = new bool[m, n];
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                visited[i, j] = false;
            }
        }
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(mat[i, j] == 0)
                   dist[i, j] = dfs(mat, m, n, i, j, visited);
            }
        }
        return;
    }
      
// Driver Code
public static void Main(string[] args)
{
    int m = 3, n = 4;
    int[,] mat = {{0, 0, 0, 1},
        {0, 0, 1, 1},
        {0, 1, 1, 0}
    };
        
    // Fills values in dist[, ]
    nearestOne(mat, m, n);
       
    // print distance matrix
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
            Console.Write(dist[i, j] + " ");
        Console.WriteLine();
    }
}
}
  
// This code is contributed by phasing17


Javascript




let MAX = 1000;
function dfs(mat,  m,  n, i, j, visited)
    // here we are validating if current coordinate is
    // out of bound or already visited or not
    if(i<0||j<0||i>=m||j>=n|| visited[i][j]==true)
     return MAX;
       
     //we reach the cell having 1 so, return 
     if(mat[i][j]==1)  
         return 0;
       
     //otherwise first mark current coordinate visited
     visited[i][j]=true;
       
     // checking using dfs in all four direction to get min for the 
     // nearest 1 +1 for the current cell
     let val=1+Math.min(dfs(mat,m,n,i+1,j,visited),Math.min(dfs(mat,m,n,i-1,j,visited),
                Math.min(dfs(mat,m,n,i,j+1,visited),dfs(mat,m,n,i,j-1,visited))));
                    
     //backtrack so that other path when reach can use this cell               
    visited[i][j]=false;
    return val;
                           
}
  
// Function to find the nearest '1'
function nearestOne(mat,  m,  n,dist)
{
    let visited = new Array(m);
    for(let i=0;i<m;i++)
        visited[i]=new Array(n);
    for(let i=0;i<m;i++)
    for(let j=0;j<n;j++)
        visited[i][j]= false;
    for(let i=0;i<m;i++)
    {
        for(let j=0;j<n;j++)
        {
            if(mat[i][j]==0)
               dist[i][j]=dfs(mat,m,n,i,j,visited);
        }
    }
    return;
}
  
    let m = 3, n = 4;
    let mat = [[0, 0, 0, 1],
        [0, 0, 1, 1],
        [0, 1, 1, 0]];
    // distance matrix which stores the distance of
    // nearest '1'
    let dist = new Array(m);
    for(let i=0;i<m;i++)
        dist[i]=new Array(n);
    for(let i=0;i<m;i++)
    for(let j=0;j<n;j++)
        dist[i][j] = 0;
    // Fills values in dist[][]
    nearestOne(mat, m, n,dist);
      
    // print distance matrix
    console.log(dist);
     
   // This code is contributed by garg28harsh.


Output

3 2 1 0 
2 1 0 0 
1 0 0 1 

Time Complexity: Time complexity of above algorithm is O(m*n)*O(m+n), where m and n are no. of rows and columns of matrix . since we have used two loops for traversing through each cell of matrix which will take O(m*n) and for calling DFS function for the cell having 0 which will take O(m+n) . In worst case all the cell contains 0 . so, we have to call DFS function for each cell which increase the time complexity . 

So, This algorithm will might gives Time Limit Exceed for some of the testcases.

An efficient solution for this problem is to use BFS. Here is the algorithm to solve this problem : 

  • Take distance matrix dist[m][n] and initialize it with INT_MAX.
  • Now traverse the matrix and make_pair(i,j) of indices of cell (i, j) having value ‘1’ and push this pair into queue and update dist[i][j] = 0 because distance of ‘1’ from itself will be always 0.
  • Now pop elements from queue one by one until it gets empty and call BFS on it.
  • Here we need to find the distance of nearest one and we are calling BFS for the cells having ‘1’, so whenever we take adjacent of popped element from queue, we try to minimize the distance by putting condition if (dist[i][j]+1) < dist[ADCi][ADCj]. Then we update the distance of adjacent element in the distance matrix and push this adjacent in the queue to complete the BFS traversal and filling the complete distance matrix.
  • After completing the BFS traversal each cell of distance matrix will contain the distance of nearest ‘1’.

Implementation:

C++




// C++ program to find the minimum distance from a
// "1" in binary matrix.
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000;
  
// distance matrix which stores the distance of
// nearest '1'
int dist[MAX][MAX];
  
// Function to find the nearest '1'
void nearestOne(int mat[][MAX], int m, int n)
{
    // two array when respective values of newx and
    // newy are added to (i,j) it gives up, down,
    // left or right adjacent of (i,j) cell
    int newx[] = { -1, 0, 1, 0 };
    int newy[] = { 0, -1, 0, 1 };
  
    // queue of pairs to store nodes for bfs
    queue<pair<int, int> > q;
  
    // traverse matrix and make pair of indices of
    // cell (i,j) having value '1' and push them
    // in queue
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            dist[i][j] = INT_MAX;
  
            if (mat[i][j] == 1) {
                // distance of '1' from itself is always 0
                dist[i][j] = 0;
  
                // make pair and push it in queue
                q.push(make_pair(i, j));
            }
        }
    }
  
    // now do bfs traversal
    // pop element from queue one by one until it gets empty
    // pair element to hold the currently popped element
    pair<int, int> popped;
    while (!q.empty()) {
        popped = q.front();
        q.pop();
  
        // coordinate of currently popped node
        int x = popped.first;
        int y = popped.second;
  
        // now check for all adjacent of popped element
        for (int i = 0; i < 4; i++) {
            int adjx = x + newx[i];
            int adjy = y + newy[i];
  
            // if new coordinates are within boundary and
            // we can minimize the distance of adjacent
            // then update the distance of adjacent in
            // distance matrix and push this adjacent
            // element in queue for further bfs
            if (adjx >= 0 && adjx < m && adjy >= 0
                && adjy < n
                && dist[adjx][adjy] > dist[x][y] + 1) {
                // update distance
                dist[adjx][adjy] = dist[x][y] + 1;
                q.push(make_pair(adjx, adjy));
            }
        }
    }
}
  
// Driver program to run the case
int main()
{
    int m = 3, n = 4;
    int mat[][MAX] = { { 0, 0, 0, 1 },
                       { 0, 0, 1, 1 },
                       { 0, 1, 1, 0 } };
  
    // Fills values in dist[][]
    nearestOne(mat, m, n);
  
    // print distance matrix
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
            cout << dist[i][j] << " ";
        cout << endl;
    }
    return 0;
}


Java




// Java program to find the minimum distance from a
// "1" in binary matrix.
import java.util.*;
  
class gfg2 {
  static int MAX = 1000;
  
  // a node in queue
  static class pair {
    int first, second;
    pair(int f, int s)
    {
      first = f;
      second = s;
    }
  }
  
  // distance matrix which stores the distance of
  // nearest '1'
  static int[][] dist;
  
  // Function to find the nearest '1'
  static void nearestOne(int mat[][], int m, int n)
  {
    // two array when respective values of newx and
    // newy are added to (i,j) it gives up, down,
    // left or right adjacent of (i,j) cell
    int newx[] = { -1, 0, 1, 0 };
    int newy[] = { 0, -1, 0, 1 };
  
    // queue of pairs to store nodes for bfs
    Queue<pair> q = new ArrayDeque<>();
  
    // traverse matrix and make pair of indices of
    // cell (i,j) having value '1' and push them
    // in queue
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        dist[i][j] = Integer.MAX_VALUE;
  
        if (mat[i][j] == 1) {
          // distance of '1' from itself is always
          // 0
          dist[i][j] = 0;
  
          // make pair and push it in queue
          q.add(new pair(i, j));
        }
      }
    }
  
    // now do bfs traversal
    // pop element from queue one by one until it gets
    // empty pair element to hold the currently popped
    // element
    pair popped;
    while (!q.isEmpty()) {
      popped = q.peek();
      q.remove();
  
      // coordinate of currently popped node
      int x = popped.first;
      int y = popped.second;
  
      // now check for all adjacent of popped element
      for (int i = 0; i < 4; i++) {
        int adjx = x + newx[i];
        int adjy = y + newy[i];
  
        // if new coordinates are within boundary
        // and we can minimize the distance of
        // adjacent then update the distance of
        // adjacent in distance matrix and push this
        // adjacent element in queue for further bfs
        if (adjx >= 0 && adjx < m && adjy >= 0
            && adjy < n
            && dist[adjx][adjy] > dist[x][y] + 1) {
          // update distance
          dist[adjx][adjy] = dist[x][y] + 1;
          q.add(new pair(adjx, adjy));
        }
      }
    }
  }
  
  // Driver program to run the case
  public static void main(String[] args)
  {
    int m = 3, n = 4;
    dist = new int[MAX][MAX];
    int mat[][] = { { 0, 0, 0, 1 },
                   { 0, 0, 1, 1 },
                   { 0, 1, 1, 0 } };
  
    // Fills values in dist[][]
    nearestOne(mat, m, n);
  
    // print distance matrix
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++)
        System.out.print(dist[i][j] + " ");
      System.out.println();
    }
  }
}
// This code is contributed by karandeep1234


Python3




# Python3 program to find the minimum distance from a
# "1" in binary matrix.
MAX = 1000
INT_MAX = (2**32)
  
# distance matrix which stores the distance of
# nearest '1'
dist = [[0 for i in range(MAX)] for j in range(MAX)]
  
# Function to find the nearest '1'
  
  
def nearestOne(mat, m, n):
  
    # two array when respective values of newx and
    # newy are added to (i,j) it gives up, down,
    # left or right adjacent of (i,j) cell
    newx = [-1, 0, 1, 0]
    newy = [0, -1, 0, 1]
  
    # queue of pairs to store nodes for bfs
    q = []
  
    # traverse matrix and make pair of indices of
    # cell (i,j) having value '1' and push them
    # in queue
    for i in range(m):
        for j in range(n):
            dist[i][j] = INT_MAX
            if (mat[i][j] == 1):
  
                # distance of '1' from itself is always 0
                dist[i][j] = 0
  
                # make pair and push it in queue
                q.append([i, j])
  
    # now do bfs traversal
    # pop element from queue one by one until it gets empty
    # pair element to hold the currently popped element
    popped = []
    while (len(q)):
        popped = q[0]
        q.pop(0)
  
        # coordinate of currently popped node
        x = popped[0]
        y = popped[1]
  
        # now check for all adjacent of popped element
        for i in range(4):
  
            adjx = x + newx[i]
            adjy = y + newy[i]
  
            # if new coordinates are within boundary and
            # we can minimize the distance of adjacent
            # then update the distance of adjacent in
            # distance matrix and push this adjacent
            # element in queue for further bfs
            if (adjx >= 0 and adjx < m and adjy >= 0 and
                    adjy < n and dist[adjx][adjy] > dist[x][y] + 1):
  
                # update distance
                dist[adjx][adjy] = dist[x][y] + 1
                q.append([adjx, adjy])
  
  
# Driver code
m = 3
n = 4
mat = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 0]]
  
# Fills values in dist[][]
nearestOne(mat, m, n)
  
# print distance matrix
for i in range(m):
    for j in range(n):
        print(dist[i][j], end=" ")
    print()
  
# This code is contributed by shubhamsingh10


C#




// C# program to find the minimum distance from a
// "1" in binary matrix.
using System;
using System.Collections;
using System.Collections.Generic;
  
class gfg2 {
  static int MAX = 1000;
  
  // a node in queue
  public class pair {
    public int first, second;
    public pair(int f, int s)
    {
      first = f;
      second = s;
    }
  }
  
  // distance matrix which stores the distance of
  // nearest '1'
  static int[, ] dist;
  
  // Function to find the nearest '1'
  static void nearestOne(int[, ] mat, int m, int n)
  {
    // two array when respective values of newx and
    // newy are added to (i,j) it gives up, down,
    // left or right adjacent of (i,j) cell
    int[] newx = { -1, 0, 1, 0 };
    int[] newy = { 0, -1, 0, 1 };
  
    // queue of pairs to store nodes for bfs
    Queue<pair> q = new Queue<pair>();
  
    // traverse matrix and make pair of indices of
    // cell (i,j) having value '1' and push them
    // in queue
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        dist[i, j] = Int32.MaxValue;
  
        if (mat[i, j] == 1) {
          // distance of '1' from itself is always
          // 0
          dist[i, j] = 0;
  
          // make pair and push it in queue
          q.Enqueue(new pair(i, j));
        }
      }
    }
  
    // now do bfs traversal
    // pop element from queue one by one until it gets
    // empty pair element to hold the currently popped
    // element
    pair popped;
    while (q.Count != 0) {
      popped = q.Peek();
      q.Dequeue();
  
      // coordinate of currently popped node
      int x = popped.first;
      int y = popped.second;
  
      // now check for all adjacent of popped element
      for (int i = 0; i < 4; i++) {
        int adjx = x + newx[i];
        int adjy = y + newy[i];
  
        // if new coordinates are within boundary
        // and we can minimize the distance of
        // adjacent then update the distance of
        // adjacent in distance matrix and push this
        // adjacent element in queue for further bfs
        if (adjx >= 0 && adjx < m && adjy >= 0
            && adjy < n
            && dist[adjx, adjy] > dist[x, y] + 1) {
          // update distance
          dist[adjx, adjy] = dist[x, y] + 1;
          q.Enqueue(new pair(adjx, adjy));
        }
      }
    }
  }
  
  // Driver program to run the case
  public static void Main(string[] args)
  {
    int m = 3, n = 4;
    dist = new int[MAX, MAX];
    int[, ] mat = { { 0, 0, 0, 1 },
                   { 0, 0, 1, 1 },
                   { 0, 1, 1, 0 } };
  
    // Fills values in dist[][]
    nearestOne(mat, m, n);
  
    // print distance matrix
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++)
        Console.Write(dist[i, j] + " ");
      Console.WriteLine();
    }
  }
}
  
// This code is contributed by karandeep1234


Javascript




<script>
  
// JavaScript program to find the minimum distance from a
// "1" in binary matrix.
const MAX = 1000
INT_MAX = (2**32)
  
// distance matrix which stores the distance of
// nearest '1'
let dist = new Array(MAX).fill(0).map(()=>new Array(MAX).fill(0))
  
// Function to find the nearest '1'
function nearestOne(mat, m, n){
      
    // two array when respective values of newx and
    // newy are added to (i,j) it gives up, down,
    // left or right adjacent of (i,j) cell
    let newx = [-1, 0, 1, 0]
    let newy = [0, -1, 0, 1]
      
    // queue of pairs to store nodes for bfs
    let q = []
      
    // traverse matrix and make pair of indices of
    // cell (i,j) having value '1' and push them
    // in queue
    for(let i=0;i<m;i++){
        for(let j=0;j<n;j++){
            dist[i][j] = INT_MAX
            if (mat[i][j] == 1){
                  
                // distance of '1' from itself is always 0
                dist[i][j] = 0
                  
                // make pair and push it in queue
                q.push([i, j])
            }
        }
    }
      
    // now do bfs traversal
    // pop element from queue one by one until it gets empty
    // pair element to hold the currently popped element
    let popped = []
    while (q.length){
        popped = q.shift()
          
        // coordinate of currently popped node
        let x = popped[0]
        let y = popped[1]
          
        // now check for all adjacent of popped element
        for(let i=0;i<4;i++){
              
            let adjx = x + newx[i]
            let adjy = y + newy[i]
              
            // if new coordinates are within boundary and
            // we can minimize the distance of adjacent
            // then update the distance of adjacent in
            // distance matrix and push this adjacent
            // element in queue for further bfs
            if (adjx >= 0 && adjx < m && adjy >= 0 &&
                adjy < n && dist[adjx][adjy] > dist[x][y] + 1){
                  
                // update distance
                dist[adjx][adjy] = dist[x][y] + 1
                q.push([adjx, adjy])
            }
        }
    }
}
  
// Driver code
let m = 3
let n = 4
let mat= [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 0]]
  
// Fills values in dist[][]
nearestOne(mat, m, n)
  
// print distance matrix
for(let i=0;i<m;i++){
    for(let j=0;j<n;j++){
        document.write(dist[i][j]," ")
    }
    document.write("</br>")
}
  
// This code is contributed by shinjanpatra
  
</script>


Output

3 2 1 0 
2 1 0 0 
1 0 0 1 

Since, we cannot do better than O(m*n) time complexity but we can still do better in space complexity with O(1) space.

The Logic behind this algo is that, if at any cell, if we know the distance of its all four direction cell than we just have to take the minimum of all four direction plus 1 for the current cell to be calculated.

We have to compute from top to bottom and left to right for each cell, but this will left uncomputed for bottom right cells. So, we run this approach in 2 phases, if we get 1 we blindly fill 0 as distance of 1 with 1 is 0 else we take the minimum of top and left cell and add 1 to it.

Now, again run two loop and calculate for bottom to top and right to left cell , but here instead of blindly taking minimum of bottom and right, we will take minimum of current value of cell, right and bottom and add 1 to it.

Below is the implementation of the above approach:

C++




#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000;
   
  
// Function to find the nearest '1'
void nearestOne(int mat[][MAX], int m, int n)
{
    //top to bottom and left to right
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(mat[i][j]==0)
               {
                   int top=i-1>=0 ? mat[i-1][j]:MAX;
                    int left=j-1>=0? mat[i][j-1]:MAX;
                    mat[i][j]=min(top,left)+1;
               }
               //As distance between cell having 1 with nearest cell 1 is 0
              else
              {
                mat[i][j]=0;
              }
        }
    }
    //bottom to top and right to left
        for(int i=m-1;i>=0;i--)
        {
            for(int j=n-1;j>=0;j--)
            {
                int bottom=i+1<m? mat[i+1][j]:MAX;
                int right=j+1<n? mat[i][j+1]:MAX;
                mat[i][j]=min(mat[i][j],min(bottom,right)+1);
            }
        }  
    return;
}
  
  
int main()
{
    int m = 3, n = 4;
    int mat[][MAX] = {{0, 0, 0, 1},
        {0, 0, 1, 1},
        {0, 1, 1, 0}
    };
    
    // solution distance is updated in mat[][]
    nearestOne(mat, m, n);
    // print distance 
    for (int i=0; i<m; i++)
    {
        for (int j=0; j<n; j++)
            cout << mat[i][j] << " ";
        cout << endl;
    }
    return 0;
}


Java




/*package whatever //do not write package name here */
  
import java.io.*;
  
class GFG 
{
    public static int MAX = 1000;
    
    public static void nearestOne(int mat[][], int m, int n)
    {
        //top to bottom and left to right
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(mat[i][j] == 0)
                   {
                       int top = i - 1 >= 0 ? mat[i - 1][j]:MAX;
                        int left = j - 1 >= 0? mat[i][j - 1]:MAX;
                        mat[i][j] = Math.min(top,left) + 1;
                   }
                   //As distance between cell having 1 with nearest cell 1 is 0
                  else
                  {
                    mat[i][j] = 0;
                  }
            }
        }
        //bottom to top and right to left
            for(int i = m - 1; i >= 0; i--)
            {
                for(int j = n - 1; j >= 0; j--)
                {
                    int bottom = i + 1<m? mat[i+1][j]:MAX;
                    int right = j + 1<n? mat[i][j+1]:MAX;
                    mat[i][j] = Math.min(mat[i][j],Math.min(bottom,right)+1);
                }
            }  
        return;
    }
      
    public static void main (String[] args) 
    {
        int m = 3, n = 4;
        int[][] mat = { {0, 0, 0, 1},
                           {0, 0, 1, 1},
                           {0, 1, 1, 0} };
  
        // solution distance is updated in mat[][]
        nearestOne(mat, m, n);
        // print distance 
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
                System.out.print(mat[i][j] + " ");
            System.out.print("\n");
        }
    }
}
  
// This code is contributed by kothavvsaakash.


C#




using System;
using System.Collections.Generic;
  
class GFG 
{
    public static int MAX = 1000;
    
    public static void nearestOne(int[,] mat, int m, int n)
    {
        //top to bottom and left to right
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(mat[i, j] == 0)
                   {
                       int top = i - 1 >= 0 ? mat[i - 1, j]:MAX;
                        int left = j - 1 >= 0? mat[i, j - 1]:MAX;
                        mat[i, j] = Math.Min(top,left) + 1;
                   }
                   //As distance between cell having 1 with nearest cell 1 is 0
                  else
                  {
                    mat[i, j] = 0;
                  }
            }
        }
        //bottom to top and right to left
            for(int i = m - 1; i >= 0; i--)
            {
                for(int j = n - 1; j >= 0; j--)
                {
                    int bottom = i + 1<m? mat[i+1, j]:MAX;
                    int right = j + 1<n? mat[i, j+1]:MAX;
                    mat[i, j] = Math.Min(mat[i, j],Math.Min(bottom,right)+1);
                }
            }  
        return;
    }
      
    public static void Main (string[] args) 
    {
        int m = 3, n = 4;
        int[, ] mat = { {0, 0, 0, 1},
                           {0, 0, 1, 1},
                           {0, 1, 1, 0} };
  
        // solution distance is updated in mat[, ]
        nearestOne(mat, m, n);
        // print distance 
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
                Console.Write(mat[i, j] + " ");
            Console.Write("\n");
        }
    }
}
  
// This code is contributed by phasing17.


Javascript




let MAX = 1000;
   
// Function to find the nearest '1'
function nearestOne(mat, m, n)
{
    //top to bottom and left to right
    for(var i=0;i<m;i++)
    {
        for(var j=0;j<n;j++)
        {
            if(mat[i][j]==0)
               {
                   var top=i-1>=0 ? mat[i-1][j]:MAX;
                    var left=j-1>=0? mat[i][j-1]:MAX;
                    mat[i][j]=Math.min(top,left)+1;
               }
               //As distance between cell having 1 with nearest cell 1 is 0
              else
              {
                mat[i][j]=0;
              }
        }
    }
    //bottom to top and right to left
        for(var i=m-1;i>=0;i--)
        {
            for(var j=n-1;j>=0;j--)
            {
                var bottom=i+1<m? mat[i+1][j]:MAX;
                var right=j+1<n? mat[i][j+1]:MAX;
                mat[i][j]=Math.min(mat[i][j],Math.min(bottom,right)+1);
            }
        }  
    return;
}
  
  
var m = 3, n = 4;
var mat = [[0, 0, 0, 1],
           [0, 0, 1, 1],
           [0, 1, 1, 0]
    ];
    
// solution distance is updated in mat[][]
nearestOne(mat, m, n);
  
// print distance 
for (var i=0; i<m; i++)
    console.log(mat[i].join(" "))
      
// This code is contributed by phasing17.


Python3




MAX = 1000
  
# Function to find the nearest '1'
def nearestOne(mat, m, n):
    # top to bottom and left to right
    for i in range(m):
        for j in range(n):
            if mat[i][j] == 0:
                top = mat[i-1][j] if i-1 >= 0 else MAX
                left = mat[i][j-1] if j-1 >= 0 else MAX
                mat[i][j] = min(top, left) + 1
            # As distance between cell having 1 with nearest cell 1 is 0
            else:
                mat[i][j] = 0
  
    # bottom to top and right to left
    for i in range(m-1, -1, -1):
        for j in range(n-1, -1, -1):
            bottom = mat[i+1][j] if i+1 < m else MAX
            right = mat[i][j+1] if j+1 < n else MAX
            mat[i][j] = min(mat[i][j], min(bottom, right) + 1)
  
    return
  
m = 3
n = 4
mat = [[0, 0, 0, 1],
       [0, 0, 1, 1],
       [0, 1, 1, 0]]
  
# solution distance is updated in mat[][]
nearestOne(mat, m, n)
  
# print distance
for i in range(m):
    for j in range(n):
        print(mat[i][j], end=" ")
    print()
# This code is contributed by Prince Kumar


Output

3 2 1 0 
2 1 0 0 
1 0 0 1 

Time Complexity: O(m*n), where m and n are the number of rows and columns of the given matrix respectively.
Auxiliary Space: O(1)

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads