Shortest distance between two cells in a matrix or grid

Last Updated : 13 May, 2025

Given a 2D matrix mat[][] of size n × m. The task is to find the shortest distance from a source cell ('s') to a destination cell ('d'), by only moving through valid cells ('*'). We are not allowed to move through '0' cells, and movement is restricted to the four directions: up, down, left, and right. If it is not possible to reach, return -1.
Note: Only one source and one destination can be assumed in the input matrix.

Examples: 

Input: mat[][] = [[ '0', '*', '0', 's' ],
[ '*', '*', '*', '*' ],
[ '0', '*', '0', '*' ],
[ '*', 'd', '*', '*' ]]
Output: 5
Explanation: One of the shortest path is: (0,3) -> (1,3) -> (1,2) -> (1,1) -> (2,1) -> (3,1). Total steps = 5.

Input: mat[][] = [ [ '0', '*', '0', 's' ],
[ '*', '0', '*', '0' ],
[ '0', '*', '0', '*' ],
[ 'd', '*', '*', '*' ] ]
Output: -1
Explanation: No path exists from 's' to 'd' due to blocked cells ('0').

Input: mat[][] = [[ 's', '*', '*', '*' ],
[ 'd', '0', '*', '0' ]]
Output: 1

Using Breadth First Search - O(n*m) Time and O(n*m) Space 

The idea is to use Breadth-First Search (BFS) to explore the matrix level by level to find the shortest path from 's' (source) to 'd' (destination). The thought process is that BFS guarantees the shortest path in an unweighted grid, making it ideal for this problem. We use a queue to track the current cell and distance, and a visited matrix to avoid revisiting cells.

Steps to implement the above idea:

  • Create a visited matrix of the same size as input to keep track of visited cells.
  • Traverse the matrix to find the source 's', mark it visited and add it to the queue with distance 0.
  • While the queue is not empty, extract the current cell and check if it is the destination 'd'.
  • For each of the four directions, compute the new cell, and if it’s valid, add it to the queue with distance +1.
  • If destination is never reached after BFS ends, return -1 to indicate no valid path exists.
C++
// C++ program to find the shortest distance from 
// source to destination in a 2D matrix using BFS
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

// Function to check if the given cell is within bounds,
// not a blocked cell ('0'), and not already visited
bool isValid(int row, int col, int n, int m,
             vector<vector<char>> &mat,
             vector<vector<bool>> &visited) {

    return row >= 0 && row < n &&
           col >= 0 && col < m &&
           mat[row][col] != '0' &&
           !visited[row][col];
}

// BFS function to find the shortest distance
// from 's' to 'd' in the matrix
int shortestPath(vector<vector<char>> &mat) {

    int n = mat.size();   
    int m = mat[0].size();

    // Direction vectors for moving: up, down, left, right
    vector<int> dRow = {-1, 1, 0, 0};
    vector<int> dCol = {0, 0, -1, 1};

    // Visited matrix to keep track of explored cells
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    
    // Queue to perform BFS: stores {row, col, distance}
    queue<vector<int>> q;

    // Find the source 's' in the matrix 
    // and start BFS from it
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {

            if (mat[i][j] == 's') {

                q.push({i, j, 0});

                visited[i][j] = true;

                break;
            }
        }
    }

    // Standard BFS loop
    while (!q.empty()) {

        vector<int> curr = q.front();
        q.pop();

        int row = curr[0];
        int col = curr[1];
        int dist = curr[2];

        // If destination 'd' is reached, return the distance
        if (mat[row][col] == 'd') {
            return dist;
        }

        // Explore all four adjacent directions
        for (int i = 0; i < 4; i++) {

            int newRow = row + dRow[i];
            int newCol = col + dCol[i];

            // If new cell is valid and can be visited
            if (isValid(newRow, newCol, n, m, mat, visited)) {

                // Mark the new cell as visited
                visited[newRow][newCol] = true;

                // Push the new cell with updated distance
                q.push({newRow, newCol, dist + 1});
            }
        }
    }

    // If no path to destination is found, return -1
    return -1;
}

// Driver code
int main() {

    vector<vector<char>> mat = {
        {'0', '*', '0', 's'},
        {'*', '*', '*', '*'},
        {'0', '*', '0', '*'},
        {'*', 'd', '*', '*'}
    };

    cout << shortestPath(mat);

    return 0;
}
Java
// Java program to find the shortest distance from 
// source to destination in a 2D matrix using BFS
import java.util.*;

class GfG {

    // Function to check if the given cell is within bounds,
    // not a blocked cell ('0'), and not already visited
    static boolean isValid(int row, int col, int n, int m,
                           char[][] mat,
                           boolean[][] visited) {

        return row >= 0 && row < n &&
               col >= 0 && col < m &&
               mat[row][col] != '0' &&
               !visited[row][col];
    }

    // BFS function to find the shortest distance
    // from 's' to 'd' in the matrix
    static int shortestPath(char[][] mat) {

        int n = mat.length;    
        int m = mat[0].length;

        // Direction vectors for moving: up, down, left, right
        int[] dRow = {-1, 1, 0, 0};
        int[] dCol = {0, 0, -1, 1};

        // Visited matrix to keep track of explored cells
        boolean[][] visited = new boolean[n][m];

        // Queue to perform BFS: stores {row, col, distance}
        Queue<int[]> q = new LinkedList<>();

        // Find the source 's' in the matrix 
        // and start BFS from it
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                if (mat[i][j] == 's') {

                    q.offer(new int[]{i, j, 0});

                    visited[i][j] = true;

                    break;
                }
            }
        }

        // Standard BFS loop
        while (!q.isEmpty()) {

            int[] curr = q.poll();

            int row = curr[0];
            int col = curr[1];
            int dist = curr[2];

            // If destination 'd' is reached, return the distance
            if (mat[row][col] == 'd') {
                return dist;
            }

            // Explore all four adjacent directions
            for (int i = 0; i < 4; i++) {

                int newRow = row + dRow[i];
                int newCol = col + dCol[i];

                // If new cell is valid and can be visited
                if (isValid(newRow, newCol, n, m, mat, visited)) {

                    // Mark the new cell as visited
                    visited[newRow][newCol] = true;

                    // Push the new cell with updated distance
                    q.offer(new int[]{newRow, newCol, dist + 1});
                }
            }
        }

        // If no path to destination is found, return -1
        return -1;
    }

    public static void main(String[] args) {

        char[][] mat = {
            {'0', '*', '0', 's'},
            {'*', '*', '*', '*'},
            {'0', '*', '0', '*'},
            {'*', 'd', '*', '*'}
        };

        System.out.println(shortestPath(mat));
    }
}
Python
# Python program to find the shortest distance from 
# source to destination in a 2D matrix using BFS
from collections import deque

# Function to check if the given cell is within bounds,
# not a blocked cell ('0'), and not already visited
def isValid(row, col, n, m, mat, visited):

    return row >= 0 and row < n and \
           col >= 0 and col < m and \
           mat[row][col] != '0' and \
           not visited[row][col]

# BFS function to find the shortest distance
# from 's' to 'd' in the matrix
def shortestPath(mat):

    n = len(mat)    
    m = len(mat[0])

    # Direction vectors for moving: up, down, left, right
    dRow = [-1, 1, 0, 0]
    dCol = [0, 0, -1, 1]

    # Visited matrix to keep track of explored cells
    visited = [[False for _ in range(m)] for _ in range(n)]

    # Queue to perform BFS: stores [row, col, distance]
    q = deque()

    # Find the source 's' in the matrix 
    # and start BFS from it
    for i in range(n):
        for j in range(m):

            if mat[i][j] == 's':

                q.append([i, j, 0])

                visited[i][j] = True

                break

    # Standard BFS loop
    while q:

        curr = q.popleft()

        row = curr[0]
        col = curr[1]
        dist = curr[2]

        # If destination 'd' is reached, return the distance
        if mat[row][col] == 'd':
            return dist

        # Explore all four adjacent directions
        for i in range(4):

            newRow = row + dRow[i]
            newCol = col + dCol[i]

            # If new cell is valid and can be visited
            if isValid(newRow, newCol, n, m, mat, visited):

                # Mark the new cell as visited
                visited[newRow][newCol] = True

                # Push the new cell with updated distance
                q.append([newRow, newCol, dist + 1])

    # If no path to destination is found, return -1
    return -1

if __name__ == "__main__":

    mat = [
        ['0', '*', '0', 's'],
        ['*', '*', '*', '*'],
        ['0', '*', '0', '*'],
        ['*', 'd', '*', '*']
    ]

    print(shortestPath(mat))
C#
// C# program to find the shortest distance from 
// source to destination in a 2D matrix using BFS
using System;
using System.Collections.Generic;

class GfG {

    // Function to check if the given cell is within bounds,
    // not a blocked cell ('0'), and not already visited
    static bool isValid(int row, int col, int n, int m,
                        char[][] mat,
                        bool[][] visited) {

        return row >= 0 && row < n &&
               col >= 0 && col < m &&
               mat[row][col] != '0' &&
               !visited[row][col];
    }

    // BFS function to find the shortest distance
    // from 's' to 'd' in the matrix
    static int shortestPath(char[][] mat) {

        int n = mat.Length;    
        int m = mat[0].Length;

        // Direction vectors for moving: up, down, left, right
        int[] dRow = {-1, 1, 0, 0};
        int[] dCol = {0, 0, -1, 1};

        // Visited matrix to keep track of explored cells
        bool[][] visited = new bool[n][];
        for (int i = 0; i < n; i++) {
            visited[i] = new bool[m];
        }

        // Queue to perform BFS: stores {row, col, distance}
        Queue<int[]> q = new Queue<int[]>();

        // Find the source 's' in the matrix 
        // and start BFS from it
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                if (mat[i][j] == 's') {

                    q.Enqueue(new int[]{i, j, 0});

                    visited[i][j] = true;

                    break;
                }
            }
        }

        // Standard BFS loop
        while (q.Count > 0) {

            int[] curr = q.Dequeue();

            int row = curr[0];
            int col = curr[1];
            int dist = curr[2];

            // If destination 'd' is reached, return the distance
            if (mat[row][col] == 'd') {
                return dist;
            }

            // Explore all four adjacent directions
            for (int i = 0; i < 4; i++) {

                int newRow = row + dRow[i];
                int newCol = col + dCol[i];

                // If new cell is valid and can be visited
                if (isValid(newRow, newCol, n, m, mat, visited)) {

                    // Mark the new cell as visited
                    visited[newRow][newCol] = true;

                    // Push the new cell with updated distance
                    q.Enqueue(new int[]{newRow, newCol, dist + 1});
                }
            }
        }

        // If no path to destination is found, return -1
        return -1;
    }

    static void Main(string[] args) {

        char[][] mat = new char[][] {
            new char[] {'0', '*', '0', 's'},
            new char[] {'*', '*', '*', '*'},
            new char[] {'0', '*', '0', '*'},
            new char[] {'*', 'd', '*', '*'}
        };

        Console.WriteLine(shortestPath(mat));
    }
}
JavaScript
// JavaScript program to find the shortest distance from 
// source to destination in a 2D matrix using BFS

// Function to check if the given cell is within bounds,
// not a blocked cell ('0'), and not already visited
function isValid(row, col, n, m, mat, visited) {

    return row >= 0 && row < n &&
           col >= 0 && col < m &&
           mat[row][col] !== '0' &&
           !visited[row][col];
}

// BFS function to find the shortest distance
// from 's' to 'd' in the matrix
function shortestPath(mat) {

    let n = mat.length;    
    let m = mat[0].length;

    // Direction vectors for moving: up, down, left, right
    let dRow = [-1, 1, 0, 0];
    let dCol = [0, 0, -1, 1];

    // Visited matrix to keep track of explored cells
    let visited = Array.from({ length: n }, () =>
        Array(m).fill(false)
    );

    // Queue to perform BFS: stores [row, col, distance]
    let q = [];

    // Find the source 's' in the matrix 
    // and start BFS from it
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {

            if (mat[i][j] === 's') {

                q.push([i, j, 0]);

                visited[i][j] = true;

                break;
            }
        }
    }

    // Standard BFS loop
    while (q.length > 0) {

        let curr = q.shift();

        let row = curr[0];
        let col = curr[1];
        let dist = curr[2];

        // If destination 'd' is reached, return the distance
        if (mat[row][col] === 'd') {
            return dist;
        }

        // Explore all four adjacent directions
        for (let i = 0; i < 4; i++) {

            let newRow = row + dRow[i];
            let newCol = col + dCol[i];

            // If new cell is valid and can be visited
            if (isValid(newRow, newCol, n, m, mat, visited)) {

                // Mark the new cell as visited
                visited[newRow][newCol] = true;

                // Push the new cell with updated distance
                q.push([newRow, newCol, dist + 1]);
            }
        }
    }

    // If no path to destination is found, return -1
    return -1;
}

// Driver Code
let mat = [
    ['0', '*', '0', 's'],
    ['*', '*', '*', '*'],
    ['0', '*', '0', '*'],
    ['*', 'd', '*', '*']
];

console.log(shortestPath(mat));

Output
5

 

Comment