Open In App

Shortest distance between two cells in a matrix or grid

Last Updated : 22 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a matrix of N*M order. Find the shortest distance from a source cell to a destination cell, traversing through limited cells only. Also you can move only up, down, left and right. If found output the distance else -1. 
s represents ‘source’ 
d represents ‘destination’ 
* represents cell you can travel 
0 represents cell you can not travel 
This problem is meant for single source and destination.
Examples: 
 

Input : {'0', '*', '0', 's'},
        {'*', '0', '*', '*'},
        {'0', '*', '*', '*'},
        {'d', '*', '*', '*'}
Output : 6

Input :  {'0', '*', '0', 's'},
         {'*', '0', '*', '*'},
         {'0', '*', '*', '*'},
         {'d', '0', '0', '0'}
Output :  -1

 

The idea is to BFS (breadth first search) on matrix cells. Note that we can always use BFS to find shortest path if graph is unweighted. 
 

  1. Store each cell as a node with their row, column values and distance from source cell.
  2. Start BFS with source cell.
  3. Make a visited array with all having “false” values except ‘0’cells which are assigned “true” values as they can not be traversed.
  4. Keep updating distance from source value in each move.
  5. Return distance when destination is met, else return -1 (no path exists in between source and destination).

 

CPP




// C++ Code implementation for above problem
#include <bits/stdc++.h>
using namespace std;
 
#define N 4
#define M 4
 
// QItem for current location and distance
// from source location
class QItem {
public:
    int row;
    int col;
    int dist;
    QItem(int x, int y, int w)
        : row(x), col(y), dist(w)
    {
    }
};
 
int minDistance(char grid[N][M])
{
    QItem source(0, 0, 0);
 
    // To keep track of visited QItems. Marking
    // blocked cells as visited.
    bool visited[N][M];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++)
        {
            if (grid[i][j] == '0')
                visited[i][j] = true;
            else
                visited[i][j] = false;
 
            // Finding source
            if (grid[i][j] == 's')
            {
               source.row = i;
               source.col = j;
            }
        }
    }
 
    // applying BFS on matrix cells starting from source
    queue<QItem> q;
    q.push(source);
    visited[source.row][source.col] = true;
    while (!q.empty()) {
        QItem p = q.front();
        q.pop();
 
        // Destination found;
        if (grid[p.row][p.col] == 'd')
            return p.dist;
 
        // moving up
        if (p.row - 1 >= 0 &&
            visited[p.row - 1][p.col] == false) {
            q.push(QItem(p.row - 1, p.col, p.dist + 1));
            visited[p.row - 1][p.col] = true;
        }
 
        // moving down
        if (p.row + 1 < N &&
            visited[p.row + 1][p.col] == false) {
            q.push(QItem(p.row + 1, p.col, p.dist + 1));
            visited[p.row + 1][p.col] = true;
        }
 
        // moving left
        if (p.col - 1 >= 0 &&
            visited[p.row][p.col - 1] == false) {
            q.push(QItem(p.row, p.col - 1, p.dist + 1));
            visited[p.row][p.col - 1] = true;
        }
 
         // moving right
        if (p.col + 1 < M &&
            visited[p.row][p.col + 1] == false) {
            q.push(QItem(p.row, p.col + 1, p.dist + 1));
            visited[p.row][p.col + 1] = true;
        }
    }
    return -1;
}
 
// Driver code
int main()
{
    char grid[N][M] = { { '0', '*', '0', 's' },
                        { '*', '0', '*', '*' },
                        { '0', '*', '*', '*' },
                        { 'd', '*', '*', '*' } };
 
    cout << minDistance(grid);
    return 0;
}


Java




/*package whatever //do not write package name here */
// Java Code implementation for above problem
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
 
// QItem for current location and distance
// from source location
class QItem {
  int row;
  int col;
  int dist;
  public QItem(int row, int col, int dist)
  {
    this.row = row;
    this.col = col;
    this.dist = dist;
  }
}
 
public class Maze {
  private static int minDistance(char[][] grid)
  {
    QItem source = new QItem(0, 0, 0);
     
    // To keep track of visited QItems. Marking
    // blocked cells as visited.
    firstLoop:
    for (int i = 0; i < grid.length; i++) {
      for (int j = 0; j < grid[i].length; j++)
      {
         
        // Finding source
        if (grid[i][j] == 's') {
          source.row = i;
          source.col = j;
          break firstLoop;
        }
      }
    }
     
    // applying BFS on matrix cells starting from source
    Queue<QItem> queue = new LinkedList<>();
    queue.add(new QItem(source.row, source.col, 0));
 
    boolean[][] visited
      = new boolean[grid.length][grid[0].length];
    visited[source.row][source.col] = true;
 
    while (queue.isEmpty() == false) {
      QItem p = queue.remove();
       
      // Destination found;
      if (grid[p.row][p.col] == 'd')
        return p.dist;
 
      // moving up
      if (isValid(p.row - 1, p.col, grid, visited)) {
        queue.add(new QItem(p.row - 1, p.col,
                            p.dist + 1));
        visited[p.row - 1][p.col] = true;
      }
 
      // moving down
      if (isValid(p.row + 1, p.col, grid, visited)) {
        queue.add(new QItem(p.row + 1, p.col,
                            p.dist + 1));
        visited[p.row + 1][p.col] = true;
      }
 
      // moving left
      if (isValid(p.row, p.col - 1, grid, visited)) {
        queue.add(new QItem(p.row, p.col - 1,
                            p.dist + 1));
        visited[p.row][p.col - 1] = true;
      }
 
      // moving right
      if (isValid(p.row, p.col + 1, grid,
                  visited)) {
        queue.add(new QItem(p.row, p.col + 1,
                            p.dist + 1));
        visited[p.row][p.col + 1] = true;
      }
    }
    return -1;
  }
   
  // checking where it's valid or not
  private static boolean isValid(int x, int y,
                                 char[][] grid,
                                 boolean[][] visited)
  {
    if (x >= 0 && y >= 0 && x < grid.length
        && y < grid[0].length && grid[x][y] != '0'
        && visited[x][y] == false) {
      return true;
    }
    return false;
  }
   
  // Driver code
  public static void main(String[] args)
  {
    char[][] grid = { { '0', '*', '0', 's' },
                     { '*', '0', '*', '*' },
                     { '0', '*', '*', '*' },
                     { 'd', '*', '*', '*' } };
 
    System.out.println(minDistance(grid));
  }
}
 
// This code is contributed by abhikelge21.


Python3




# Python3 Code implementation for above problem
 
# QItem for current location and distance
# from source location
class QItem:
    def __init__(self, row, col, dist):
        self.row = row
        self.col = col
        self.dist = dist
 
    def __repr__(self):
        return f"QItem({self.row}, {self.col}, {self.dist})"
 
def minDistance(grid):
    source = QItem(0, 0, 0)
 
    # Finding the source to start from
    for row in range(len(grid)):
        for col in range(len(grid[row])):
            if grid[row][col] == 's':
                source.row = row
                source.col = col
                break
 
    # To maintain location visit status
    visited = [[False for _ in range(len(grid[0]))]
               for _ in range(len(grid))]
     
    # applying BFS on matrix cells starting from source
    queue = []
    queue.append(source)
    visited[source.row][source.col] = True
    while len(queue) != 0:
        source = queue.pop(0)
 
        # Destination found;
        if (grid[source.row][source.col] == 'd'):
            return source.dist
 
        # moving up
        if isValid(source.row - 1, source.col, grid, visited):
            queue.append(QItem(source.row - 1, source.col, source.dist + 1))
            visited[source.row - 1][source.col] = True
 
        # moving down
        if isValid(source.row + 1, source.col, grid, visited):
            queue.append(QItem(source.row + 1, source.col, source.dist + 1))
            visited[source.row + 1][source.col] = True
 
        # moving left
        if isValid(source.row, source.col - 1, grid, visited):
            queue.append(QItem(source.row, source.col - 1, source.dist + 1))
            visited[source.row][source.col - 1] = True
 
        # moving right
        if isValid(source.row, source.col + 1, grid, visited):
            queue.append(QItem(source.row, source.col + 1, source.dist + 1))
            visited[source.row][source.col + 1] = True
 
    return -1
 
 
# checking where move is valid or not
def isValid(x, y, grid, visited):
    if ((x >= 0 and y >= 0) and
        (x < len(grid) and y < len(grid[0])) and
            (grid[x][y] != '0') and (visited[x][y] == False)):
        return True
    return False
 
# Driver code
if __name__ == '__main__':
    grid = [['0', '*', '0', 's'],
            ['*', '0', '*', '*'],
            ['0', '*', '*', '*'],
            ['d', '*', '*', '*']]
 
    print(minDistance(grid))
 
    # This code is contributed by sajalmittaldei.


C#





Javascript




<script>
 
// Javascript Code implementation for above problem
var N = 4;
var M = 4;
 
// QItem for current location and distance
// from source location
class QItem {
     
    constructor(x, y, w)
    {
        this.row = x;
        this.col = y;
        this.dist = w;
    }
};
 
function minDistance(grid)
{
    var source = new QItem(0, 0, 0);
 
    // To keep track of visited QItems. Marking
    // blocked cells as visited.
    var visited = Array.from(Array(N), ()=>Array(M).fill(0));
    for (var i = 0; i < N; i++) {
        for (var j = 0; j < M; j++)
        {
            if (grid[i][j] == '0')
                visited[i][j] = true;
            else
                visited[i][j] = false;
 
            // Finding source
            if (grid[i][j] == 's')
            {
               source.row = i;
               source.col = j;
            }
        }
    }
 
    // applying BFS on matrix cells starting from source
    var q = [];
    q.push(source);
    visited[source.row][source.col] = true;
    while (q.length!=0) {
        var p = q[0];
        q.shift();
 
        // Destination found;
        if (grid[p.row][p.col] == 'd')
            return p.dist;
 
        // moving up
        if (p.row - 1 >= 0 &&
            visited[p.row - 1][p.col] == false) {
            q.push(new QItem(p.row - 1, p.col, p.dist + 1));
            visited[p.row - 1][p.col] = true;
        }
 
        // moving down
        if (p.row + 1 < N &&
            visited[p.row + 1][p.col] == false) {
            q.push(new QItem(p.row + 1, p.col, p.dist + 1));
            visited[p.row + 1][p.col] = true;
        }
 
        // moving left
        if (p.col - 1 >= 0 &&
            visited[p.row][p.col - 1] == false) {
            q.push(new QItem(p.row, p.col - 1, p.dist + 1));
            visited[p.row][p.col - 1] = true;
        }
 
         // moving right
        if (p.col + 1 < M &&
            visited[p.row][p.col + 1] == false) {
            q.push(new QItem(p.row, p.col + 1, p.dist + 1));
            visited[p.row][p.col + 1] = true;
        }
    }
    return -1;
}
 
// Driver code
var grid = [ [ '0', '*', '0', 's' ],
                    [ '*', '0', '*', '*' ],
                    [ '0', '*', '*', '*' ],
                    [ 'd', '*', '*', '*' ] ];
document.write(minDistance(grid));
 
// This code is contributed by rrrtnx.
 
</script>


Output

6

Time Complexity: O(N x M) 
Auxiliary Space: O(N x M)

 



Previous Article
Next Article

Similar Reads

Java Program for Shortest distance between two cells in a matrix or grid
Given a matrix of N*M order. Find the shortest distance from a source cell to a destination cell, traversing through limited cells only. Also you can move only up, down, left and right. If found output the distance else -1. s represents 'source' d represents 'destination' * represents cell you can travel 0 represents cell you can not travel This pr
3 min read
C++ Program for Shortest distance between two cells in a matrix or grid
Given a matrix of N*M order. Find the shortest distance from a source cell to a destination cell, traversing through limited cells only. Also you can move only up, down, left and right. If found output the distance else -1. s represents 'source' d represents 'destination' * represents cell you can travel 0 represents cell you can not travel This pr
3 min read
Count cells in a grid from which maximum number of cells can be reached by K vertical or horizontal jumps
Given a matrix mat[][] of dimensions N*M and a positive integer K, the task is to find the number of cells in a grid from which maximum cells can be reached by K jumps in the vertical or horizontal direction. Examples: Input: N = 3, M = 3, K = 2Output: 4Explanation:The cells represented as X are the cells from which maximum cells (= 2) can be reach
8 min read
Path to reach border cells from a given cell in a 2D Grid without crossing specially marked cells
Given a matrix of dimensions N*M consisting of characters 'M', '#', '.' and only a single instance of 'A'. The task is to print any one path from the cell having value A to any border cell of the matrix according to the following rules: Every second the path from cell 'A' can move in all four adjacent cells having '.' characters only. The character
15+ min read
Count of cells in a matrix which give a Fibonacci number when the count of adjacent cells is added
Given an M x N matrix mat[][]. The task is to count the number of good cells in the matrix. A cell will be good if the sum of the cell value and the number of the adjacent cells is a Fibonacci number.Examples: Input: mat[][] = { {1, 2}, {3, 4}} Output: 2 Only the cells mat[0][0] and mat[1][0] are good. i.e. (1 + 2) = 3 and (3 + 2) = 5 are both Fibo
9 min read
Count of cells in a matrix whose adjacent cells's sum is prime Number
Given a M x N matrix mat[][], the task is to count the number of cells which have the sum of its adjacent cells equal to a prime number. For a cell x[i][j], only x[i+1][j], x[i-1][j], x[i][j+1] and x[i][j-1] are the adjacent cells.Examples: Input : mat[][] = {{1, 3}, {2, 5}} Output :2 Explanation: Only the cells mat[0][0] and mat[1][1] satisfying t
10 min read
Shortest XY distance in Grid
Given an N*M grid of characters 'O', 'X', and 'Y'. Find the minimum Manhattan distance between an X and a Y. Manhattan Distance : | row_index_x - row_index_y | + | column_index_x - column_index_y | Examples: Input: N = 4, M = 4grid[][] = {{X, O, O, O} {O, Y, O, Y} {X, X, O, O} {O, Y, O, O}}Output: 1Explanation:{{X, O, O, O}{O, Y, O, Y}{X, X, O, O}{
12 min read
Shortest path from a source cell to a destination cell of a Binary Matrix through cells consisting only of 1s
Given a binary matrix mat[][] of dimensions of N * M and pairs of integers src and dest representing source and destination cells respectively, the task is to find the shortest sequence of moves from the given source cell to the destination cell via cells consisting only of 1s. The allowed moves are moving a cell left (L), right (R), up (U), and do
15+ min read
Minimum Numbers of cells that are connected with the smallest path between 3 given cells
Given coordinates of 3 cells (X1, Y1), (X2, Y2) and (X3, Y3) of a matrix. The task is to find the minimum path which connects all three of these cells and print the count of all the cells that are connected through this path. Note: Only possible moves are up, down, left and right. Examples: Input: X1 = 0, Y1 = 0, X2 = 1, Y2 = 1, X3 = 2 and Y3 = 2 O
7 min read
Calculate the Manhattan Distance between two cells of given 2D array
Given a 2D array of size M * N and two points in the form (X1, Y1) and (X2 , Y2) where X1 and X2 represents the rows and Y1 and Y2 represents the column. The task is to calculate the Manhattan distance between the given points. Examples: Input: M = 5, N = 5, X1 = 1, Y1 = 2, X2 = 3, Y2 = 3Output: 3Explanation: As per the definition, the Manhattan th
4 min read
three90RightbarBannerImg