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++
// 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 arrayint minDistance[row + 1][col + 1], visited[row + 1][col + 1];Â
// Queue for BFSqueue<pair<int, int> > que;Â
// Function to find whether the move is valid or notbool 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 gridint 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 codeint 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
// Java implementation of the approachimport java.util.*;class GFG{Â Â Â Â Â // Pair classstatic 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 arraystatic int minDistance[][] = Â Â Â Â Â Â Â Â Â Â Â Â new int[row + 1][col + 1], Â Â Â Â Â Â Â Â Â Â Â Â visited[][] = new int[row + 1][col + 1];Â
// Queue for BFSstatic Queue<Pair > que = new LinkedList<>();Â
// Function to find whether the move is valid or notstatic 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 gridstatic 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 codepublic 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 |
Python3
# Python 3 implementation of the approachÂ
row = 5col = 5Â
# Global variables for grid, minDistance and visited arrayminDistance = [[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 BFSque = [[0,0]]Â
# Function to find whether the move is valid or notdef 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 griddef 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 codeif __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#
// C# implementation of above approachusing 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) |
Javascript
<script>// Javascript implementation of the approachÂ
// Pair classclass Pair{Â Â Â Â constructor(a, b)Â Â Â Â {Â Â Â Â Â Â Â Â this.first = a;Â Â Â Â Â Â Â Â this.second = b;Â Â Â Â }}Â
let row = 5;let col = 5;Â
// Global variables for grid, minDistance and visited arraylet 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 BFSlet que = [];Â
// Function to find whether the move is valid or notfunction 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 gridfunction _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 codelet 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
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
