Given a binary grid of order r * c and an initial position. The task is to find the minimum distance from the source to get to the any corner of the grid. A move can be made to a cell grid[i][j] only if grid[i][j] = 0 and only left, right, up and down movements are permitted. If no valid path exists then print -1.
Examples:
Input: i = 1, j = 1, grid[][] = {{0, 0, 1}, {0, 0, 0}, {1, 1, 1}}
Output: 2
(1, 1) -> (1, 0) -> (0, 0)
Input: i = 0, j = 0, grid[][] = {{0, 1}, {1, 1}}
Output: 0
Source is already a corner of the grid.
Approach:
- If source is already any of the corner then print 0.
- Start traversing the grid starting with source using BFS as :
- Insert cell position in queue.
- Pop element from queue and mark it visited.
- For each valid move adjacent to popped one, insert the cell position into queue.
- On each move, update the minimum distance of the cell from initial position.
- After the completion of the BFS, find the minimum distance from source to every corner.
- Print the minimum among these in the end.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
#define row 5 #define col 5 // Global variables for grid, minDistance and visited array int minDistance[row + 1][col + 1], visited[row + 1][col + 1];
// Queue for BFS queue<pair< int , int > > que;
// Function to find whether the move is valid or not bool isValid( int grid[][col], int i, int j)
{ if (i < 0 || j < 0
|| j >= col || i >= row
|| grid[i][j] || visited[i][j])
return false ;
return true ;
} // Function to return the minimum distance // from source to the end of the grid int minDistance( int grid[][col],
int sourceRow, int sourceCol)
{ // If source is one of the destinations
if ((sourceCol == 0 && sourceRow == 0)
|| (sourceCol == col - 1 && sourceRow == 0)
|| (sourceCol == 0 && sourceRow == row - 1)
|| (sourceCol == col - 1 && sourceRow == row - 1))
return 0;
// Set minimum value
int minFromSource = row * col;
// Precalculate minDistance of each grid with R * C
for ( int i = 0; i < row; i++)
for ( int j = 0; j < col; j++)
minDistance[i][j] = row * col;
// Insert source position in queue
que.push(make_pair(sourceRow, sourceCol));
// Update minimum distance to visit source
minDistance[sourceRow][sourceCol] = 0;
// Set source to visited
visited[sourceRow][sourceCol] = 1;
// BFS approach for calculating the minDistance
// of each cell from source
while (!que.empty()) {
// Iterate over all four cells adjacent
// to current cell
pair< int , int > cell = que.front();
// Initialize position of current cell
int cellRow = cell.first;
int cellCol = cell.second;
// Cell below the current cell
if (isValid(grid, cellRow + 1, cellCol)) {
// Push new cell to the queue
que.push(make_pair(cellRow + 1, cellCol));
// Update one of its neighbor's distance
minDistance[cellRow + 1][cellCol]
= min(minDistance[cellRow + 1][cellCol],
minDistance[cellRow][cellCol] + 1);
visited[cellRow + 1][cellCol] = 1;
}
// Above the current cell
if (isValid(grid, cellRow - 1, cellCol)) {
que.push(make_pair(cellRow - 1, cellCol));
minDistance[cellRow - 1][cellCol]
= min(minDistance[cellRow - 1][cellCol],
minDistance[cellRow][cellCol] + 1);
visited[cellRow - 1][cellCol] = 1;
}
// Right cell
if (isValid(grid, cellRow, cellCol + 1)) {
que.push(make_pair(cellRow, cellCol + 1));
minDistance[cellRow][cellCol + 1]
= min(minDistance[cellRow][cellCol + 1],
minDistance[cellRow][cellCol] + 1);
visited[cellRow][cellCol + 1] = 1;
}
// Left cell
if (isValid(grid, cellRow, cellCol - 1)) {
que.push(make_pair(cellRow, cellCol - 1));
minDistance[cellRow][cellCol - 1]
= min(minDistance[cellRow][cellCol - 1],
minDistance[cellRow][cellCol] + 1);
visited[cellRow][cellCol - 1] = 1;
}
// Pop the visited cell
que.pop();
}
int i;
// Minimum distance to the corner
// of the first row, first column
minFromSource = min(minFromSource,
minDistance[0][0]);
// Minimum distance to the corner
// of the last row, first column
minFromSource = min(minFromSource,
minDistance[row - 1][0]);
// Minimum distance to the corner
// of the last row, last column
minFromSource = min(minFromSource,
minDistance[row - 1][col - 1]);
// Minimum distance to the corner
// of the first row, last column
minFromSource = min(minFromSource,
minDistance[0][col - 1]);
// If no path exists
if (minFromSource == row * col)
return -1;
// Return the minimum distance
return minFromSource;
} // Driver code int main()
{ int sourceRow = 3, sourceCol = 3;
int grid[row][col] = { 1, 1, 1, 0, 0,
0, 0, 1, 0, 1,
0, 0, 1, 0, 1,
1, 0, 0, 0, 1,
1, 1, 0, 1, 0 };
cout << minDistance(grid, sourceRow, sourceCol);
return 0;
} |
// Java implementation of the approach import java.util.*;
class GFG
{ // Pair class static class Pair
{ int first,second;
Pair( int a, int b)
{
first = a;
second = b;
}
} static int row = 5 ;
static int col = 5 ;
// Global variables for grid, minDistance and visited array static int minDistance[][] =
new int [row + 1 ][col + 1 ],
visited[][] = new int [row + 1 ][col + 1 ];
// Queue for BFS static Queue<Pair > que = new LinkedList<>();
// Function to find whether the move is valid or not static boolean isValid( int grid[][], int i, int j)
{ if (i < 0 || j < 0
|| j >= col || i >= row
|| grid[i][j] != 0 || visited[i][j] != 0 )
return false ;
return true ;
} // Function to return the minimum distance // from source to the end of the grid static int minDistance( int grid[][],
int sourceRow, int sourceCol)
{ // If source is one of the destinations
if ((sourceCol == 0 && sourceRow == 0 )
|| (sourceCol == col - 1 && sourceRow == 0 )
|| (sourceCol == 0 && sourceRow == row - 1 )
|| (sourceCol == col - 1 && sourceRow == row - 1 ))
return 0 ;
// Set minimum value
int minFromSource = row * col;
// Precalculate minDistance of each grid with R * C
for ( int i = 0 ; i < row; i++)
for ( int j = 0 ; j < col; j++)
minDistance[i][j] = row * col;
// Insert source position in queue
que.add( new Pair(sourceRow, sourceCol));
// Update minimum distance to visit source
minDistance[sourceRow][sourceCol] = 0 ;
// Set source to visited
visited[sourceRow][sourceCol] = 1 ;
// BFS approach for calculating the minDistance
// of each cell from source
while (que.size() > 0 )
{
// Iterate over all four cells adjacent
// to current cell
Pair cell = que.peek();
// Initialize position of current cell
int cellRow = cell.first;
int cellCol = cell.second;
// Cell below the current cell
if (isValid(grid, cellRow + 1 , cellCol))
{
// add new cell to the queue
que.add( new Pair(cellRow + 1 , cellCol));
// Update one of its neighbor's distance
minDistance[cellRow + 1 ][cellCol]
= Math.min(minDistance[cellRow + 1 ][cellCol],
minDistance[cellRow][cellCol] + 1 );
visited[cellRow + 1 ][cellCol] = 1 ;
}
// Above the current cell
if (isValid(grid, cellRow - 1 , cellCol))
{
que.add( new Pair(cellRow - 1 , cellCol));
minDistance[cellRow - 1 ][cellCol]
= Math.min(minDistance[cellRow - 1 ][cellCol],
minDistance[cellRow][cellCol] + 1 );
visited[cellRow - 1 ][cellCol] = 1 ;
}
// Right cell
if (isValid(grid, cellRow, cellCol + 1 ))
{
que.add( new Pair(cellRow, cellCol + 1 ));
minDistance[cellRow][cellCol + 1 ]
= Math.min(minDistance[cellRow][cellCol + 1 ],
minDistance[cellRow][cellCol] + 1 );
visited[cellRow][cellCol + 1 ] = 1 ;
}
// Left cell
if (isValid(grid, cellRow, cellCol - 1 ))
{
que.add( new Pair(cellRow, cellCol - 1 ));
minDistance[cellRow][cellCol - 1 ]
= Math.min(minDistance[cellRow][cellCol - 1 ],
minDistance[cellRow][cellCol] + 1 );
visited[cellRow][cellCol - 1 ] = 1 ;
}
// remove the visited cell
que.remove();
}
int i;
// Minimum distance to the corner
// of the first row, first column
minFromSource = Math.min(minFromSource,
minDistance[ 0 ][ 0 ]);
// Minimum distance to the corner
// of the last row, first column
minFromSource = Math.min(minFromSource,
minDistance[row - 1 ][ 0 ]);
// Minimum distance to the corner
// of the last row, last column
minFromSource = Math.min(minFromSource,
minDistance[row - 1 ][col - 1 ]);
// Minimum distance to the corner
// of the first row, last column
minFromSource = Math.min(minFromSource,
minDistance[ 0 ][col - 1 ]);
// If no path exists
if (minFromSource == row * col)
return - 1 ;
// Return the minimum distance
return minFromSource;
} // Driver code public static void main(String args[])
{ int sourceRow = 3 , sourceCol = 3 ;
int grid[][] = { { 1 , 1 , 1 , 0 , 0 },
{ 0 , 0 , 1 , 0 , 1 },
{ 0 , 0 , 1 , 0 , 1 },
{ 1 , 0 , 0 , 0 , 1 },
{ 1 , 1 , 0 , 1 , 0 } };
System.out.println(minDistance(grid, sourceRow, sourceCol));
} } // This code is contributed by Arnab Kundu |
# Python 3 implementation of the approach row = 5
col = 5
# Global variables for grid, minDistance and visited array minDistance = [[ 0 for i in range (col + 1 )] for j in range (row + 1 )]
visited = [[ 0 for i in range (col + 1 )] for j in range (row + 1 )]
# Queue for BFS que = [[ 0 , 0 ]]
# Function to find whether the move is valid or not def isValid(grid,i,j):
if (i < 0 or j < 0 or j > = col or
i > = row or grid[i][j] or visited[i][j]):
return False
return True
# Function to return the minimum distance # from source to the end of the grid def minDistance1(grid,sourceRow,sourceCol):
# If source is one of the destinations
if ((sourceCol = = 0 and sourceRow = = 0 ) or
(sourceCol = = col - 1 and sourceRow = = 0 ) or
(sourceCol = = 0 or sourceRow = = row - 1 ) or
(sourceCol = = col - 1 and sourceRow = = row - 1 )):
return 0
# Set minimum value
minFromSource = row * col
# Precalculate minDistance of each grid with R * C
for i in range (row):
for j in range (col):
minDistance[i][j] = row * col
# Insert source position in queue
que.append([sourceRow, sourceCol])
# Update minimum distance to visit source
minDistance[sourceRow][sourceCol] = 0
# Set source to visited
visited[sourceRow][sourceCol] = 1
# BFS approach for calculating the minDistance
# of each cell from source
while ( len (que)! = 0 ):
# Iterate over all four cells adjacent
# to current cell
cell = que[ 0 ]
# Initialize position of current cell
cellRow = cell[ 0 ]
cellCol = cell[ 1 ]
# Cell below the current cell
if (isValid(grid, cellRow + 1 , cellCol)):
# Push new cell to the queue
que.append([cellRow + 1 , cellCol])
# Update one of its neighbor's distance
minDistance[cellRow + 1 ][cellCol] = min (minDistance[cellRow + 1 ][cellCol],
minDistance[cellRow][cellCol] + 1 )
visited[cellRow + 1 ][cellCol] = 1
# Above the current cell
if (isValid(grid, cellRow - 1 , cellCol)):
que.append([cellRow - 1 , cellCol])
minDistance[cellRow - 1 ][cellCol] = min (minDistance[cellRow - 1 ][cellCol],
minDistance[cellRow][cellCol] + 1 )
visited[cellRow - 1 ][cellCol] = 1
# Right cell
if (isValid(grid, cellRow, cellCol + 1 )):
que.append([cellRow, cellCol + 1 ])
minDistance[cellRow][cellCol + 1 ] = min (minDistance[cellRow][cellCol + 1 ],
minDistance[cellRow][cellCol] + 1 )
visited[cellRow][cellCol + 1 ] = 1
# Left cell
if (isValid(grid, cellRow, cellCol - 1 )):
que.append([cellRow, cellCol - 1 ])
minDistance[cellRow][cellCol - 1 ] = min (minDistance[cellRow][cellCol - 1 ],
minDistance[cellRow][cellCol] + 1 )
visited[cellRow][cellCol - 1 ] = 1
# Pop the visited cell
que.remove(que[ 0 ])
# Minimum distance to the corner
# of the first row, first column
minFromSource = min (minFromSource, minDistance[ 0 ][ 0 ])
# Minimum distance to the corner
# of the last row, first column
minFromSource = min (minFromSource, minDistance[row - 1 ][ 0 ])
# Minimum distance to the corner
# of the last row, last column
minFromSource = min (minFromSource,minDistance[row - 1 ][col - 1 ])
# Minimum distance to the corner
# of the first row, last column
minFromSource = min (minFromSource, minDistance[ 0 ][col - 1 ])
# If no path exists
if (minFromSource = = row * col):
return - 1
# Return the minimum distance
return minFromSource
# Driver code if __name__ = = '__main__' :
sourceRow = 3
sourceCol = 3
grid = [[ 1 , 1 , 1 , 0 , 0 ],
[ 0 , 0 , 1 , 0 , 1 ],
[ 0 , 0 , 1 , 0 , 1 ],
[ 1 , 0 , 0 , 0 , 1 ],
[ 1 , 1 , 0 , 1 , 0 ]]
print (minDistance1(grid, sourceRow, sourceCol))
# This code is contributed by # Surendra_Gangwar |
// C# implementation of above approach using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
// Global variables for grid, minDistance and visited
// array
static class Globals {
// global int
public static int row = 5;
public static int col = 5;
// Global variables for grid, minDistance and
// visited array
public static int [, ] minDistance
= new int [row + 1, col + 1];
public static int [, ] visited
= new int [row + 1, col + 1];
// Queue for BFS
public static Queue<KeyValuePair< int , int > > que
= new Queue<KeyValuePair< int , int > >();
}
// Function to find whether the move is valid or not
static bool isValid( int [, ] grid, int i, int j)
{
if (i < 0 || j < 0 || j >= Globals.col
|| i >= Globals.row || grid[i, j] != 0
|| Globals.visited[i, j] != 0)
return false ;
return true ;
}
// Function to return the minimum distance
// from source to the end of the grid
static int minDistance1( int [, ] grid, int sourceRow,
int sourceCol)
{
// If source is one of the destinations
if ((sourceCol == 0 && sourceRow == 0)
|| (sourceCol == Globals.col - 1
&& sourceRow == 0)
|| (sourceCol == 0
&& sourceRow == Globals.row - 1)
|| (sourceCol == Globals.col - 1
&& sourceRow == Globals.row - 1))
return 0;
// Set minimum value
int minFromSource = Globals.row * Globals.col;
// Precalculate minDistance of each grid with R * C
for ( int i = 0; i < Globals.row; i++)
for ( int j = 0; j < Globals.col; j++)
Globals.minDistance[i, j]
= Globals.row * Globals.col;
// Insert source position in queue
Globals.que.Enqueue( new KeyValuePair< int , int >(
sourceRow, sourceCol));
// Update minimum distance to visit source
Globals.minDistance[sourceRow, sourceCol] = 0;
// Set source to visited
Globals.visited[sourceRow, sourceCol] = 1;
// BFS approach for calculating the minDistance
// of each cell from source
while (Globals.que.Count > 0) {
// Iterate over all four cells adjacent
// to current cell
KeyValuePair< int , int > cell
= Globals.que.Dequeue();
// Initialize position of current cell
int cellRow = cell.Key;
int cellCol = cell.Value;
// Cell below the current cell
if (isValid(grid, cellRow + 1, cellCol)) {
// Push new cell to the queue
Globals.que.Enqueue(
new KeyValuePair< int , int >(cellRow + 1,
cellCol));
// Update one of its neighbor's distance
Globals.minDistance[cellRow + 1, cellCol]
= Math.Min(
Globals.minDistance[cellRow + 1,
cellCol],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow + 1, cellCol] = 1;
}
// Above the current cell
if (isValid(grid, cellRow - 1, cellCol)) {
Globals.que.Enqueue(
new KeyValuePair< int , int >(cellRow - 1,
cellCol));
Globals.minDistance[cellRow - 1, cellCol]
= Math.Min(
Globals.minDistance[cellRow - 1,
cellCol],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow - 1, cellCol] = 1;
}
// Right cell
if (isValid(grid, cellRow, cellCol + 1)) {
Globals.que.Enqueue(
new KeyValuePair< int , int >(
cellRow, cellCol + 1));
Globals.minDistance[cellRow, cellCol + 1]
= Math.Min(
Globals.minDistance[cellRow,
cellCol + 1],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow, cellCol + 1] = 1;
}
// Left cell
if (isValid(grid, cellRow, cellCol - 1)) {
Globals.que.Enqueue(
new KeyValuePair< int , int >(
cellRow, cellCol - 1));
Globals.minDistance[cellRow, cellCol - 1]
= Math.Min(
Globals.minDistance[cellRow,
cellCol - 1],
Globals.minDistance[cellRow,
cellCol]
+ 1);
Globals.visited[cellRow, cellCol - 1] = 1;
}
}
// Minimum distance to the corner
// of the first row, first column
minFromSource = Math.Min(minFromSource,
Globals.minDistance[0, 0]);
// Minimum distance to the corner
// of the last row, first column
minFromSource = Math.Min(
minFromSource,
Globals.minDistance[Globals.row - 1, 0]);
// Minimum distance to the corner
// of the last row, last column
minFromSource = Math.Min(
minFromSource,
Globals.minDistance[Globals.row - 1,
Globals.col - 1]);
// Minimum distance to the corner
// of the first row, last column
minFromSource = Math.Min(
minFromSource,
Globals.minDistance[0, Globals.col - 1]);
// If no path exists
if (minFromSource == Globals.row * Globals.col)
return -1;
// Return the minimum distance
return minFromSource;
}
// Driver Code
static void Main()
{
int sourceRow = 3, sourceCol = 3;
int [, ] grid = { { 1, 1, 1, 0, 0 },
{ 0, 0, 1, 0, 1 },
{ 0, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 1, 1, 0, 1, 0 } };
Console.WriteLine(
minDistance1(grid, sourceRow, sourceCol));
}
} // The code is contributed by Gautam goel (gautamgoel962) |
<script> // Javascript implementation of the approach // Pair class class Pair { constructor(a, b)
{
this .first = a;
this .second = b;
}
} let row = 5; let col = 5; // Global variables for grid, minDistance and visited array let minDistance = new Array(row + 1);
let visited = new Array(row + 1);
for (let i = 0; i < row + 1; i++)
{ minDistance[i] = new Array(col+1);
visited[i] = new Array(col+1);
for (let j = 0; j < col + 1; j++)
{
minDistance[i][j] = 0;
visited[i][j] = 0;
}
} // Queue for BFS let que = []; // Function to find whether the move is valid or not function isValid(grid,i,j)
{ if (i < 0 || j < 0
|| j >= col || i >= row
|| grid[i][j] != 0 || visited[i][j] != 0)
return false ;
return true ;
} // Function to return the minimum distance // from source to the end of the grid function _minDistance(grid,sourceRow,sourceCol)
{ // If source is one of the destinations
if ((sourceCol == 0 && sourceRow == 0)
|| (sourceCol == col - 1 && sourceRow == 0)
|| (sourceCol == 0 && sourceRow == row - 1)
|| (sourceCol == col - 1 && sourceRow == row - 1))
return 0;
// Set minimum value
let minFromSource = row * col;
// Precalculate minDistance of each grid with R * C
for (let i = 0; i < row; i++)
for (let j = 0; j < col; j++)
minDistance[i][j] = row * col;
// Insert source position in queue
que.push( new Pair(sourceRow, sourceCol));
// Update minimum distance to visit source
minDistance[sourceRow][sourceCol] = 0;
// Set source to visited
visited[sourceRow][sourceCol] = 1;
// BFS approach for calculating the minDistance
// of each cell from source
while (que.length > 0)
{
// Iterate over all four cells adjacent
// to current cell
let cell = que[0];
// Initialize position of current cell
let cellRow = cell.first;
let cellCol = cell.second;
// Cell below the current cell
if (isValid(grid, cellRow + 1, cellCol))
{
// add new cell to the queue
que.push( new Pair(cellRow + 1, cellCol));
// Update one of its neighbor's distance
minDistance[cellRow + 1][cellCol]
= Math.min(minDistance[cellRow + 1][cellCol],
minDistance[cellRow][cellCol] + 1);
visited[cellRow + 1][cellCol] = 1;
}
// Above the current cell
if (isValid(grid, cellRow - 1, cellCol))
{
que.push( new Pair(cellRow - 1, cellCol));
minDistance[cellRow - 1][cellCol]
= Math.min(minDistance[cellRow - 1][cellCol],
minDistance[cellRow][cellCol] + 1);
visited[cellRow - 1][cellCol] = 1;
}
// Right cell
if (isValid(grid, cellRow, cellCol + 1))
{
que.push( new Pair(cellRow, cellCol + 1));
minDistance[cellRow][cellCol + 1]
= Math.min(minDistance[cellRow][cellCol + 1],
minDistance[cellRow][cellCol] + 1);
visited[cellRow][cellCol + 1] = 1;
}
// Left cell
if (isValid(grid, cellRow, cellCol - 1))
{
que.push( new Pair(cellRow, cellCol - 1));
minDistance[cellRow][cellCol - 1]
= Math.min(minDistance[cellRow][cellCol - 1],
minDistance[cellRow][cellCol] + 1);
visited[cellRow][cellCol - 1] = 1;
}
// remove the visited cell
que.shift();
}
let i;
// Minimum distance to the corner
// of the first row, first column
minFromSource = Math.min(minFromSource,
minDistance[0][0]);
// Minimum distance to the corner
// of the last row, first column
minFromSource = Math.min(minFromSource,
minDistance[row - 1][0]);
// Minimum distance to the corner
// of the last row, last column
minFromSource = Math.min(minFromSource,
minDistance[row - 1][col - 1]);
// Minimum distance to the corner
// of the first row, last column
minFromSource = Math.min(minFromSource,
minDistance[0][col - 1]);
// If no path exists
if (minFromSource == row * col)
return -1;
// Return the minimum distance
return minFromSource;
} // Driver code let sourceRow = 3, sourceCol = 3; let grid = [[1, 1, 1, 0, 0], [0, 0, 1, 0, 1],
[0, 0, 1, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 0, 1, 0]];
document.write(_minDistance(grid, sourceRow, sourceCol)); // This code is contributed by avanitrachhadiya2155 </script> |
4