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. 
 
- Store each cell as a node with their row, column values and distance from source cell.
- Start BFS with source cell.
- Make a visited array with all having “false” values except ‘0’cells which are assigned “true” values as they can not be traversed.
- Keep updating distance from source value in each move.
- 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>usingnamespacestd;#define N 4#define M 4// QItem for current location and distance// from source locationclassQItem {public:    introw;    intcol;    intdist;    QItem(intx, inty, intw)        : row(x), col(y), dist(w)    {    }};intminDistance(chargrid[N][M]){    QItem source(0, 0, 0);    // To keep track of visited QItems. Marking    // blocked cells as visited.    boolvisited[N][M];    for(inti = 0; i < N; i++) {        for(intj = 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')            returnp.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 codeintmain(){    chargrid[N][M] = { { '0', '*', '0', 's'},                        { '*', '0', '*', '*'},                        { '0', '*', '*', '*'},                        { 'd', '*', '*', '*'} };    cout << minDistance(grid);    return0;} | 
Java
| /*package whatever //do not write package name here */// Java Code implementation for above problemimportjava.util.LinkedList;importjava.util.Queue;importjava.util.Scanner;// QItem for current location and distance// from source locationclassQItem {  introw;  intcol;  intdist;  publicQItem(introw, intcol, intdist)  {    this.row = row;    this.col = col;    this.dist = dist;  }}publicclassMaze {  privatestaticintminDistance(char[][] grid)  {    QItem source = newQItem(0, 0, 0);        // To keep track of visited QItems. Marking    // blocked cells as visited.    firstLoop:    for(inti = 0; i < grid.length; i++) {      for(intj = 0; j < grid[i].length; j++)       {                // Finding source        if(grid[i][j] == 's') {          source.row = i;          source.col = j;          breakfirstLoop;        }      }    }        // applying BFS on matrix cells starting from source    Queue<QItem> queue = newLinkedList<>();    queue.add(newQItem(source.row, source.col, 0));    boolean[][] visited      = newboolean[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')        returnp.dist;      // moving up      if(isValid(p.row - 1, p.col, grid, visited)) {        queue.add(newQItem(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(newQItem(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(newQItem(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(newQItem(p.row, p.col + 1,                            p.dist + 1));        visited[p.row][p.col + 1] = true;      }    }    return-1;  }    // checking where it's valid or not  privatestaticbooleanisValid(intx, inty,                                 char[][] grid,                                 boolean[][] visited)  {    if(x >= 0&& y >= 0&& x < grid.length        && y < grid[0].length && grid[x][y] != '0'        && visited[x][y] == false) {      returntrue;    }    returnfalse;  }    // Driver code  publicstaticvoidmain(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 locationclassQItem:    def__init__(self, row, col, dist):        self.row =row        self.col =col        self.dist =dist    def__repr__(self):        returnf"QItem({self.row}, {self.col}, {self.dist})"defminDistance(grid):    source =QItem(0, 0, 0)    # Finding the source to start from    forrow inrange(len(grid)):        forcol inrange(len(grid[row])):            ifgrid[row][col] =='s':                source.row =row                source.col =col                break    # To maintain location visit status    visited =[[Falsefor_ inrange(len(grid[0]))]               for_ inrange(len(grid))]        # applying BFS on matrix cells starting from source    queue =[]    queue.append(source)    visited[source.row][source.col] =True    whilelen(queue) !=0:        source =queue.pop(0)        # Destination found;        if(grid[source.row][source.col] =='d'):            returnsource.dist        # moving up        ifisValid(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        ifisValid(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        ifisValid(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        ifisValid(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 notdefisValid(x, y, grid, visited):    if((x >=0andy >=0) and        (x < len(grid) andy < len(grid[0])) and            (grid[x][y] !='0') and(visited[x][y] ==False)):        returnTrue    returnFalse# Driver codeif__name__ =='__main__':    grid =[['0', '*', '0', 's'],            ['*', '0', '*', '*'],            ['0', '*', '*', '*'],            ['d', '*', '*', '*']]    print(minDistance(grid))    # This code is contributed by sajalmittaldei. | 
C#
| usingSystem;usingSystem.Collections.Generic;// C# Code implementation for above problem// QItem for current location and distance// from source locationpublicclassQItem {  publicintrow;  publicintcol;  publicintdist;  publicQItem(intx, inty, intw)  {    this.row = x;    this.col = y;    this.dist = w;  }}publicstaticclassGFG {  staticintN = 4;  staticintM = 4;  publicstaticintminDistance(char[, ] grid)  {    QItem source = newQItem(0, 0, 0);    // To keep track of visited QItems. Marking    // blocked cells as visited.    bool[, ] visited = newbool[N, M];    ;    for(inti = 0; i < N; i++) {      for(intj = 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 = newQueue<QItem>();    q.Enqueue(source);    visited[source.row, source.col] = true;    while(q.Count > 0) {      QItem p = q.Peek();      q.Dequeue();      // Destination found;      if(grid[p.row, p.col] == 'd') {        returnp.dist;      }      // moving up      if(p.row - 1 >= 0          && visited[p.row - 1, p.col] == false) {        q.Enqueue(newQItem(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.Enqueue(newQItem(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.Enqueue(newQItem(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.Enqueue(newQItem(p.row, p.col + 1,                            p.dist + 1));        visited[p.row, p.col + 1] = true;      }    }    return-1;  }  // Driver code  publicstaticvoidMain()  {    char[, ] grid = { { '0', '*', '0', 's'},                     { '*', '0', '*', '*'},                     { '0', '*', '*', '*'},                     { 'd', '*', '*', '*'} };    Console.Write(minDistance(grid));  }}// This code is contributed by Aarti_Rathi | 
Javascript
| <script>// Javascript Code implementation for above problemvarN = 4;varM = 4;// QItem for current location and distance// from source locationclass QItem {        constructor(x, y, w)    {        this.row = x;        this.col = y;        this.dist = w;    }};functionminDistance(grid){    varsource = newQItem(0, 0, 0);    // To keep track of visited QItems. Marking    // blocked cells as visited.    varvisited = Array.from(Array(N), ()=>Array(M).fill(0));    for(vari = 0; i < N; i++) {        for(varj = 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    varq = [];    q.push(source);    visited[source.row][source.col] = true;    while(q.length!=0) {        varp = q[0];        q.shift();        // Destination found;        if(grid[p.row][p.col] == 'd')            returnp.dist;        // moving up        if(p.row - 1 >= 0 &&            visited[p.row - 1][p.col] == false) {            q.push(newQItem(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(newQItem(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(newQItem(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(newQItem(p.row, p.col + 1, p.dist + 1));            visited[p.row][p.col + 1] = true;        }    }    return-1;}// Driver codevargrid = [ [ '0', '*', '0', 's'],                    [ '*', '0', '*', '*'],                    [ '0', '*', '*', '*'],                    [ 'd', '*', '*', '*'] ];document.write(minDistance(grid));// This code is contributed by rrrtnx.</script> | 
6
Time Complexity: O(N x M) 
Auxiliary Space: O(N x M)
This article is contributed by Aarti_Rathi and Prashant Singh. If you like neveropen and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the neveropen main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

 
                                    







