Open In App

Minimum distance to the corner of a grid from source

Last Updated : 20 Mar, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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:
(1, 1) -> (1, 0) -> (0, 0)
 

Input: i = 0, j = 0, grid[][] = {{0, 1}, {1, 1}} 
Output:
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 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
// 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
Python3
# 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#
// 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)
JavaScript
<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>

Output: 
4

 

Next Article
Article Tags :
Practice Tags :

Similar Reads