Given an n × m grid mat[][] consisting of the characters 'O', 'B', and 'W', where 'O' represents an open cell, 'B' represents a bomb, and 'W' represents a wall. A move can be made from a cell to any of its four adjacent cells (up, down, left, and right), and walls cannot be crossed.
Replace each cell in the grid as follows:
Replace every 'B' with 0.
Replace every 'W' with -1.
Replace every 'O' with the minimum number of moves required to reach the nearest bomb without passing through any wall. If an open cell cannot reach any bomb, replace it with -1.
Output: [[2, 1, 1], [-1, 0, 0], [-1, 1, 1]] Explanation: The wall cells (1,0) and (2,0) are replaced with -1, and the bomb cells (1,1) and (1,2) are replaced with 0. Each open cell is assigned the minimum distance to the nearest bomb without crossing any wall. Thus, the open cells (0,0), (0,1), (0,2), (2,1), and (2,2) are replaced with 2, 1, 1, 1, and 1 respectively.
Input: mat[][] = [['O', 'O'], ['O', 'O']]
Output: [[-1, -1], [-1, -1]] Explanation: There is no bomb in the grid, so none of the open cells can reach a bomb. Hence, all open cells are replaced with -1.
[Naive Approach] BFS for Every Open Cell - O((n * m) ^ 2) Time and O(n * m) Space
Since every move to an adjacent cell has the same cost (1 move), the problem is a shortest path problem in an unweighted grid. The idea here is to use BFS as the ideal choice because it explores cells level by level, ensuring that the first bomb reached is always the nearest one. Therefore, we perform a separate BFS from every open cell to compute its minimum distance to a bomb while treating walls as blocked cells.
Create an answer matrix and initialize all cells with -1.
Traverse the grid and set bombs ('B') to 0 and walls ('W') to -1.
For every open cell ('O'), perform a BFS starting from that cell.
During BFS, visit only valid and unvisited cells while skipping walls.
As soon as a bomb is reached, store the current BFS level as the minimum distance.
If the BFS finishes without reaching any bomb, keep the answer as -1.
C++
#include<bits/stdc++.h>usingnamespacestd;// Performs BFS from the given open cell and// returns the distance to the nearest bomb.intbfs(introw,intcol,vector<vector<char>>&mat){intn=mat.size();intm=mat[0].size();// Visited array for the current BFSvector<vector<bool>>visited(n,vector<bool>(m,false));queue<pair<int,int>>q;q.push({row,col});visited[row][col]=true;intdistance=0;while(!q.empty()){intsize=q.size();while(size--){autocurr=q.front();q.pop();inti=curr.first;intj=curr.second;// Bomb foundif(mat[i][j]=='B'){returndistance;}// Move Downif(i+1<n&&mat[i+1][j]!='W'&&!visited[i+1][j]){visited[i+1][j]=true;q.push({i+1,j});}// Move Upif(i-1>=0&&mat[i-1][j]!='W'&&!visited[i-1][j]){visited[i-1][j]=true;q.push({i-1,j});}// Move Rightif(j+1<m&&mat[i][j+1]!='W'&&!visited[i][j+1]){visited[i][j+1]=true;q.push({i,j+1});}// Move Leftif(j-1>=0&&mat[i][j-1]!='W'&&!visited[i][j-1]){visited[i][j-1]=true;q.push({i,j-1});}}// Move to the next BFS leveldistance++;}// No bomb is reachablereturn-1;}vector<vector<int>>findDistance(vector<vector<char>>&mat){intn=mat.size();intm=mat[0].size();// Initialize the answer matrix with -1vector<vector<int>>ans(n,vector<int>(m,-1));// Process every cell in the gridfor(inti=0;i<n;i++){for(intj=0;j<m;j++){// Bomb cellif(mat[i][j]=='B'){ans[i][j]=0;}// Wall cellelseif(mat[i][j]=='W'){ans[i][j]=-1;}// Find the nearest bomb for every open cellelse{ans[i][j]=bfs(i,j,mat);}}}returnans;}intmain(){vector<vector<char>>mat={{'O','O','O'},{'W','B','B'},{'W','O','O'}};vector<vector<int>>ans=findDistance(mat);for(auto&row:ans){for(auto&x:row){cout<<x<<" ";}cout<<endl;}return0;}
Java
importjava.util.*;classGFG{// Performs BFS from the given open cell and// returns the distance to the nearest bomb.staticintbfs(introw,intcol,char[][]mat){intn=mat.length;intm=mat[0].length;// Visited array for the current BFSboolean[][]visited=newboolean[n][m];Queue<int[]>q=newLinkedList<>();q.offer(newint[]{row,col});visited[row][col]=true;intdistance=0;while(!q.isEmpty()){intsize=q.size();while(size-->0){int[]curr=q.poll();inti=curr[0];intj=curr[1];// Bomb foundif(mat[i][j]=='B'){returndistance;}// Move Downif(i+1<n&&mat[i+1][j]!='W'&&!visited[i+1][j]){visited[i+1][j]=true;q.offer(newint[]{i+1,j});}// Move Upif(i-1>=0&&mat[i-1][j]!='W'&&!visited[i-1][j]){visited[i-1][j]=true;q.offer(newint[]{i-1,j});}// Move Rightif(j+1<m&&mat[i][j+1]!='W'&&!visited[i][j+1]){visited[i][j+1]=true;q.offer(newint[]{i,j+1});}// Move Leftif(j-1>=0&&mat[i][j-1]!='W'&&!visited[i][j-1]){visited[i][j-1]=true;q.offer(newint[]{i,j-1});}}// Move to the next BFS leveldistance++;}// No bomb is reachablereturn-1;}staticArrayList<ArrayList<Integer>>findDistance(char[][]mat){intn=mat.length;intm=mat[0].length;// Initialize the answer matrixArrayList<ArrayList<Integer>>ans=newArrayList<>();for(inti=0;i<n;i++){ans.add(newArrayList<>());for(intj=0;j<m;j++){// Bomb cellif(mat[i][j]=='B'){ans.get(i).add(0);}// Wall cellelseif(mat[i][j]=='W'){ans.get(i).add(-1);}// Find the nearest bomb for every open cellelse{ans.get(i).add(bfs(i,j,mat));}}}returnans;}publicstaticvoidmain(String[]args){char[][]mat={{'O','O','O'},{'W','B','B'},{'W','O','O'}};ArrayList<ArrayList<Integer>>ans=findDistance(mat);for(ArrayList<Integer>row:ans){for(intx:row)System.out.print(x+" ");System.out.println();}}}
Python
fromcollectionsimportdeque# Performs BFS from the given open cell and# returns the distance to the nearest bomb.defbfs(row,col,mat):n=len(mat)m=len(mat[0])# Visited array for the current BFSvisited=[[False]*mfor_inrange(n)]q=deque()q.append((row,col))visited[row][col]=Truedistance=0whileq:size=len(q)for_inrange(size):i,j=q.popleft()# Bomb foundifmat[i][j]=='B':returndistance# Move Downifi+1<nandmat[i+1][j]!='W'andnotvisited[i+1][j]:visited[i+1][j]=Trueq.append((i+1,j))# Move Upifi-1>=0andmat[i-1][j]!='W'andnotvisited[i-1][j]:visited[i-1][j]=Trueq.append((i-1,j))# Move Rightifj+1<mandmat[i][j+1]!='W'andnotvisited[i][j+1]:visited[i][j+1]=Trueq.append((i,j+1))# Move Leftifj-1>=0andmat[i][j-1]!='W'andnotvisited[i][j-1]:visited[i][j-1]=Trueq.append((i,j-1))# Move to the next BFS leveldistance+=1# No bomb is reachablereturn-1deffindDistance(mat):n=len(mat)m=len(mat[0])# Initialize the answer matrix with -1ans=[[-1]*mfor_inrange(n)]# Process every cell in the gridforiinrange(n):forjinrange(m):# Bomb cellifmat[i][j]=='B':ans[i][j]=0# Wall cellelifmat[i][j]=='W':ans[i][j]=-1# Find the nearest bomb for every open cellelse:ans[i][j]=bfs(i,j,mat)returnans# Driver Codeif__name__=="__main__":mat=[['O','O','O'],['W','B','B'],['W','O','O']]ans=findDistance(mat)forrowinans:print(*row)
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Performs BFS from the given open cell and// returns the distance to the nearest bomb.staticintBFS(introw,intcol,char[,]mat){intn=mat.GetLength(0);intm=mat.GetLength(1);// Visited array for the current BFSbool[,]visited=newbool[n,m];Queue<(int,int)>q=newQueue<(int,int)>();q.Enqueue((row,col));visited[row,col]=true;intdistance=0;while(q.Count>0){intsize=q.Count;while(size-->0){var(i,j)=q.Dequeue();// Bomb foundif(mat[i,j]=='B')returndistance;// Move Downif(i+1<n&&mat[i+1,j]!='W'&&!visited[i+1,j]){visited[i+1,j]=true;q.Enqueue((i+1,j));}// Move Upif(i-1>=0&&mat[i-1,j]!='W'&&!visited[i-1,j]){visited[i-1,j]=true;q.Enqueue((i-1,j));}// Move Rightif(j+1<m&&mat[i,j+1]!='W'&&!visited[i,j+1]){visited[i,j+1]=true;q.Enqueue((i,j+1));}// Move Leftif(j-1>=0&&mat[i,j-1]!='W'&&!visited[i,j-1]){visited[i,j-1]=true;q.Enqueue((i,j-1));}}// Move to the next BFS leveldistance++;}// No bomb is reachablereturn-1;}staticList<List<int>>findDistance(char[,]mat){intn=mat.GetLength(0);intm=mat.GetLength(1);// Initialize the answer matrix with -1List<List<int>>ans=newList<List<int>>();for(inti=0;i<n;i++){List<int>row=newList<int>();for(intj=0;j<m;j++){// Bomb cellif(mat[i,j]=='B')row.Add(0);// Wall cellelseif(mat[i,j]=='W')row.Add(-1);// Find the nearest bomb for every open cellelserow.Add(BFS(i,j,mat));}ans.Add(row);}returnans;}staticvoidMain(){char[,]mat={{'O','O','O'},{'W','B','B'},{'W','O','O'}};List<List<int>>ans=findDistance(mat);foreach(varrowinans){foreach(varxinrow)Console.Write(x+" ");Console.WriteLine();}}}
JavaScript
// Performs BFS from the given open cell and// returns the distance to the nearest bomb.functionbfs(row,col,mat){constn=mat.length;constm=mat[0].length;// Visited array for the current BFSconstvisited=Array.from({length:n},()=>Array(m).fill(false));constq=[];letfront=0;q.push([row,col]);visited[row][col]=true;letdistance=0;while(front<q.length){letsize=q.length-front;while(size--){const[i,j]=q[front++];// Bomb foundif(mat[i][j]==="B")returndistance;// Move Downif(i+1<n&&mat[i+1][j]!=="W"&&!visited[i+1][j]){visited[i+1][j]=true;q.push([i+1,j]);}// Move Upif(i-1>=0&&mat[i-1][j]!=="W"&&!visited[i-1][j]){visited[i-1][j]=true;q.push([i-1,j]);}// Move Rightif(j+1<m&&mat[i][j+1]!=="W"&&!visited[i][j+1]){visited[i][j+1]=true;q.push([i,j+1]);}// Move Leftif(j-1>=0&&mat[i][j-1]!=="W"&&!visited[i][j-1]){visited[i][j-1]=true;q.push([i,j-1]);}}// Move to the next BFS leveldistance++;}// No bomb is reachablereturn-1;}functionfindDistance(mat){constn=mat.length;constm=mat[0].length;// Initialize the answer matrix with -1constans=Array.from({length:n},()=>Array(m).fill(-1));// Process every cell in the gridfor(leti=0;i<n;i++){for(letj=0;j<m;j++){// Bomb cellif(mat[i][j]==="B")ans[i][j]=0;// Wall cellelseif(mat[i][j]==="W")ans[i][j]=-1;// Find the nearest bomb for every open cellelseans[i][j]=bfs(i,j,mat);}}returnans;}// Driver Codeconstmat=[["O","O","O"],["W","B","B"],["W","O","O"]];constans=findDistance(mat);for(constrowofans)console.log(row.join(" "));
Output
2 1 1
-1 0 0
-1 1 1
[Expected Approach] Using Multi Source BFS - O(n * m) Time and O(n * m) Space
In the previous approach, we performed a separate BFS from every open cell to find its nearest bomb. This causes the same cells to be visited repeatedly, leading to unnecessary computations.
Instead of starting a BFS from every open cell, we can reverse our perspective and start the BFS from all bomb cells simultaneously. Since BFS explores cells level by level, the first time an open cell is reached, it is guaranteed to be from its nearest bomb.
Create the answer matrix and initialize all cells with -1.
Traverse the grid, set every bomb ('B') to 0, and insert all bomb cells into the BFS queue.
Perform a BFS starting simultaneously from all bomb cells.
For each popped cell, visit all valid adjacent open cells that have not been visited.
Assign each visited open cell a distance of current distance + 1 and push it into the queue.
After the BFS finishes, unreachable open cells remain -1, while walls also remain -1.
C++
#include<bits/stdc++.h>usingnamespacestd;// Returns the minimum distance of every cell// from the nearest bomb using Multi-Source BFS.vector<vector<int>>findDistance(vector<vector<char>>&mat){intn=mat.size();intm=mat[0].size();// Initialize the answer matrix with -1vector<vector<int>>ans(n,vector<int>(m,-1));// Queue for Multi-Source BFSqueue<pair<int,int>>q;// Add all bomb cells to the queuefor(inti=0;i<n;i++){for(intj=0;j<m;j++){// Bomb cellif(mat[i][j]=='B'){ans[i][j]=0;q.push({i,j});}// Wall cellelseif(mat[i][j]=='W'){ans[i][j]=-1;}}}// Traverse all reachable cellswhile(!q.empty()){autocurr=q.front();q.pop();inti=curr.first;intj=curr.second;// Move Downif(i+1<n&&mat[i+1][j]=='O'&&ans[i+1][j]==-1){ans[i+1][j]=ans[i][j]+1;q.push({i+1,j});}// Move Upif(i-1>=0&&mat[i-1][j]=='O'&&ans[i-1][j]==-1){ans[i-1][j]=ans[i][j]+1;q.push({i-1,j});}// Move Rightif(j+1<m&&mat[i][j+1]=='O'&&ans[i][j+1]==-1){ans[i][j+1]=ans[i][j]+1;q.push({i,j+1});}// Move Leftif(j-1>=0&&mat[i][j-1]=='O'&&ans[i][j-1]==-1){ans[i][j-1]=ans[i][j]+1;q.push({i,j-1});}}returnans;}intmain(){vector<vector<char>>mat={{'O','O','O'},{'W','B','B'},{'W','O','O'}};vector<vector<int>>ans=findDistance(mat);for(auto&row:ans){for(auto&x:row){cout<<x<<" ";}cout<<endl;}return0;}
Java
importjava.util.*;classGFG{// Returns the minimum distance of every cell// from the nearest bomb using Multi-Source BFS.staticArrayList<ArrayList<Integer>>findDistance(char[][]mat){intn=mat.length;intm=mat[0].length;// Initialize the answer matrix with -1ArrayList<ArrayList<Integer>>ans=newArrayList<>();for(inti=0;i<n;i++){ans.add(newArrayList<>());for(intj=0;j<m;j++){ans.get(i).add(-1);}}// Queue for Multi-Source BFSQueue<int[]>q=newLinkedList<>();// Add all bomb cells to the queuefor(inti=0;i<n;i++){for(intj=0;j<m;j++){// Bomb cellif(mat[i][j]=='B'){ans.get(i).set(j,0);q.offer(newint[]{i,j});}// Wall cellelseif(mat[i][j]=='W'){ans.get(i).set(j,-1);}}}// Traverse all reachable cellswhile(!q.isEmpty()){int[]curr=q.poll();inti=curr[0];intj=curr[1];// Move Downif(i+1<n&&mat[i+1][j]=='O'&&ans.get(i+1).get(j)==-1){ans.get(i+1).set(j,ans.get(i).get(j)+1);q.offer(newint[]{i+1,j});}// Move Upif(i-1>=0&&mat[i-1][j]=='O'&&ans.get(i-1).get(j)==-1){ans.get(i-1).set(j,ans.get(i).get(j)+1);q.offer(newint[]{i-1,j});}// Move Rightif(j+1<m&&mat[i][j+1]=='O'&&ans.get(i).get(j+1)==-1){ans.get(i).set(j+1,ans.get(i).get(j)+1);q.offer(newint[]{i,j+1});}// Move Leftif(j-1>=0&&mat[i][j-1]=='O'&&ans.get(i).get(j-1)==-1){ans.get(i).set(j-1,ans.get(i).get(j)+1);q.offer(newint[]{i,j-1});}}returnans;}publicstaticvoidmain(String[]args){char[][]mat={{'O','O','O'},{'W','B','B'},{'W','O','O'}};ArrayList<ArrayList<Integer>>ans=findDistance(mat);for(ArrayList<Integer>row:ans){for(intx:row)System.out.print(x+" ");System.out.println();}}}
Python
fromcollectionsimportdeque# Returns the minimum distance of every cell# from the nearest bomb using Multi-Source BFS.deffindDistance(mat):n=len(mat)m=len(mat[0])# Initialize the answer matrix with -1ans=[[-1]*mfor_inrange(n)]# Queue for Multi-Source BFSq=deque()# Add all bomb cells to the queueforiinrange(n):forjinrange(m):# Bomb cellifmat[i][j]=='B':ans[i][j]=0q.append((i,j))# Wall cellelifmat[i][j]=='W':ans[i][j]=-1# Traverse all reachable cellswhileq:i,j=q.popleft()# Move Downifi+1<nandmat[i+1][j]=='O'andans[i+1][j]==-1:ans[i+1][j]=ans[i][j]+1q.append((i+1,j))# Move Upifi-1>=0andmat[i-1][j]=='O'andans[i-1][j]==-1:ans[i-1][j]=ans[i][j]+1q.append((i-1,j))# Move Rightifj+1<mandmat[i][j+1]=='O'andans[i][j+1]==-1:ans[i][j+1]=ans[i][j]+1q.append((i,j+1))# Move Leftifj-1>=0andmat[i][j-1]=='O'andans[i][j-1]==-1:ans[i][j-1]=ans[i][j]+1q.append((i,j-1))returnans# Driver Codeif__name__=="__main__":mat=[['O','O','O'],['W','B','B'],['W','O','O']]ans=findDistance(mat)forrowinans:print(*row)
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Returns the minimum distance of every cell// from the nearest bomb using Multi-Source BFS.staticList<List<int>>findDistance(char[,]mat){intn=mat.GetLength(0);intm=mat.GetLength(1);// Initialize the answer matrix with -1List<List<int>>ans=newList<List<int>>();for(inti=0;i<n;i++){List<int>row=newList<int>();for(intj=0;j<m;j++)row.Add(-1);ans.Add(row);}// Queue for Multi-Source BFSQueue<(int,int)>q=newQueue<(int,int)>();// Add all bomb cells to the queuefor(inti=0;i<n;i++){for(intj=0;j<m;j++){// Bomb cellif(mat[i,j]=='B'){ans[i][j]=0;q.Enqueue((i,j));}// Wall cellelseif(mat[i,j]=='W'){ans[i][j]=-1;}}}// Traverse all reachable cellswhile(q.Count>0){var(i,j)=q.Dequeue();// Move Downif(i+1<n&&mat[i+1,j]=='O'&&ans[i+1][j]==-1){ans[i+1][j]=ans[i][j]+1;q.Enqueue((i+1,j));}// Move Upif(i-1>=0&&mat[i-1,j]=='O'&&ans[i-1][j]==-1){ans[i-1][j]=ans[i][j]+1;q.Enqueue((i-1,j));}// Move Rightif(j+1<m&&mat[i,j+1]=='O'&&ans[i][j+1]==-1){ans[i][j+1]=ans[i][j]+1;q.Enqueue((i,j+1));}// Move Leftif(j-1>=0&&mat[i,j-1]=='O'&&ans[i][j-1]==-1){ans[i][j-1]=ans[i][j]+1;q.Enqueue((i,j-1));}}returnans;}staticvoidMain(){char[,]mat={{'O','O','O'},{'W','B','B'},{'W','O','O'}};List<List<int>>ans=findDistance(mat);foreach(varrowinans){foreach(varxinrow)Console.Write(x+" ");Console.WriteLine();}}}
JavaScript
// Returns the minimum distance of every cell// from the nearest bomb using Multi-Source BFS.functionfindDistance(mat){constn=mat.length;constm=mat[0].length;// Initialize the answer matrix with -1constans=Array.from({length:n},()=>Array(m).fill(-1));// Queue for Multi-Source BFSconstq=[];letfront=0;// Add all bomb cells to the queuefor(leti=0;i<n;i++){for(letj=0;j<m;j++){// Bomb cellif(mat[i][j]==="B"){ans[i][j]=0;q.push([i,j]);}// Wall cellelseif(mat[i][j]==="W"){ans[i][j]=-1;}}}// Traverse all reachable cellswhile(front<q.length){const[i,j]=q[front++];// Move Downif(i+1<n&&mat[i+1][j]==="O"&&ans[i+1][j]===-1){ans[i+1][j]=ans[i][j]+1;q.push([i+1,j]);}// Move Upif(i-1>=0&&mat[i-1][j]==="O"&&ans[i-1][j]===-1){ans[i-1][j]=ans[i][j]+1;q.push([i-1,j]);}// Move Rightif(j+1<m&&mat[i][j+1]==="O"&&ans[i][j+1]===-1){ans[i][j+1]=ans[i][j]+1;q.push([i,j+1]);}// Move Leftif(j-1>=0&&mat[i][j-1]==="O"&&ans[i][j-1]===-1){ans[i][j-1]=ans[i][j]+1;q.push([i,j-1]);}}returnans;}// Driver Codeconstmat=[["O","O","O"],["W","B","B"],["W","O","O"]];constans=findDistance(mat);for(constrowofans)console.log(row.join(" "));