Open In App

Count Number of Ways to Reach Destination in a Maze using BFS

Last Updated : 10 Feb, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given a maze of dimensions n x m represented by the matrix mat, where mat[i][j] = -1 represents a blocked cell and mat[i][j] = 0 represents an unblocked cell, the task is to count the number of ways to reach the bottom-right cell starting from the top-left cell by moving right (i, j+1) or down (i+1, j) in the maze using Breadth-First Search.

Note: We can only pass through unblocked cells.

Examples: 

Input: mat[][] = [[0, 0, 0, 0],
[0, -1, 0, 0],
[-1, 0, 0, 0],
[0, 0, 0, 0]];
Output: 4
Explanation: There are two blocked cells at positions (1, 1) and (2, 0).
There are 4 ways to reach the bottom-right cell:
1. Right -> Right -> Right -> Down -> Down -> Down
2. Right -> Right -> Down -> Right -> Down -> Down
3. Right -> Right -> Down -> Down -> Right -> Down
4. Right -> Right -> Down -> Down -> Down -> Right

Input: mat[][] = [[0, 0, 0],
[0, -1, 0],
[0, 0, 0]]
Output: 2
Explanation: There is one blocked cell at position (1, 1)
There are 2 ways to reach the bottom-right cell:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

Approach:

The idea is to use Breadth-First Search (BFS) to explore all possible ways to traverse a maze. The BFS approach works well because it explores paths level by level, ensuring that all potential paths are checked. The algorithm first verifies if the start or end cell is blocked; if either is, it immediately returns 0 as no traversal is possible. A queue is then initialized to store the current cell’s position, enabling iterative exploration. At each step, the algorithm dequeues a cell and checks if it has reached the bottom-right corner. If so, it increments the ways counter. For each valid neighbor (not blocked and within bounds), the neighbor is added to the queue for further exploration. The process continues until the queue is empty, meaning all possible paths have been examined.

Below is the implementation of the above approach:  

C++
// C++ code to find the number of ways in a maze
// with blocked cells using BFS
#include <bits/stdc++.h>
using namespace std;

// Function to find the number of ways using BFS
int findWays(vector<vector<int>>& mat) {
    int n = mat.size(), m = mat[0].size();

    // If starting or ending cell is blocked, return 0
    if (mat[0][0] == -1 || mat[n-1][m-1] == -1) {
        return 0;
    }

    // Queue to store the current cell and path count
    queue<pair<int, int>> q;
    q.push({0, 0});

    // Variable to store the number of ways
    int ways = 0;

    // Directions for moving right and down
    vector<pair<int, int>> directions = {{1, 0}, {0, 1}};

    while (!q.empty()) {
        auto curr = q.front();
        q.pop();

        int i = curr.first, j = curr.second;

        // If reached the bottom-right cell, increment ways
        if (i == n-1 && j == m-1) {
            ways++;
            continue;
        }

        // Explore adjacent cells (right and down)
        for (auto dir : directions) {
            int ni = i + dir.first;
            int nj = j + dir.second;

            // Check if within bounds and not blocked
            if (ni < n && nj < m && mat[ni][nj] != -1) {
                q.push({ni, nj});
            }
        }
    }

    return ways;
}

int main() {
    vector<vector<int>> mat = {{ 0,  0,  0 },
                               { 0, -1,  0 },
                               { 0,  0,  0 }};

    cout << findWays(mat);                                                  
}
Java
// Java code to find the number of ways in a maze
// with blocked cells using BFS
import java.util.*;

class GfG {

    // Function to find the number of ways using BFS
    static int findWays(int[][] mat) {
        int n = mat.length, m = mat[0].length;

        // If starting or ending cell is blocked, return 0
        if (mat[0][0] == -1 || mat[n-1][m-1] == -1) {
            return 0;
        }

        // Queue to store the current cell
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{0, 0});

        // Variable to store the number of ways
        int ways = 0;

        // Directions for moving right and down
        int[][] directions = {{1, 0}, {0, 1}};

        while (!queue.isEmpty()) {
            int[] curr = queue.poll();
            int i = curr[0], j = curr[1];

            // If reached the bottom-right cell, increment ways
            if (i == n-1 && j == m-1) {
                ways++;
                continue;
            }

            // Explore adjacent cells (right and down)
            for (int[] dir : directions) {
                int ni = i + dir[0];
                int nj = j + dir[1];

                // Check if within bounds and not blocked
                if (ni < n && nj < m && mat[ni][nj] != -1) {
                    queue.add(new int[]{ni, nj});
                }
            }
        }

        return ways;
    }

    public static void main(String[] args) {
      
        int[][] mat = { { 0, 0, 0 },
                        { 0, -1, 0 },
                        { 0, 0, 0 } };

        System.out.println(findWays(mat));
    }
}
Python
# Python code to find the number of ways in a maze
# with blocked cells using BFS
from collections import deque

def findWays(mat):
  
    n, m = len(mat), len(mat[0])

    # If starting or ending cell is blocked, return 0
    if mat[0][0] == -1 or mat[n-1][m-1] == -1:
        return 0

    # Queue to store the current cell
    q = deque([(0, 0)])

    # Variable to store the number of ways
    ways = 0

    # Directions for moving right and down
    directions = [(1, 0), (0, 1)]

    while q:
        i, j = q.popleft()

        # If reached the bottom-right cell, increment ways
        if i == n-1 and j == m-1:
            ways += 1
            continue

        # Explore adjacent cells (right and down)
        for di, dj in directions:
            ni, nj = i + di, j + dj

            # Check if within bounds and not blocked
            if 0 <= ni < n and 0 <= nj < m \
                         and mat[ni][nj] != -1:
              
                q.append((ni, nj))

    return ways

if __name__ == "__main__":

    mat = [[0, 0, 0],
           [0, -1, 0],
           [0, 0, 0]]

    print(findWays(mat))
C#
// C# code to find number of ways in a maze
// with blocked cells using BFS
using System;
using System.Collections.Generic;

class GfG {

    // Function to find ways with blocked cells
    static int findWays(int[,] mat) {
        int n = mat.GetLength(0), m = mat.GetLength(1);

        // If starting or ending cell is blocked, return 0
        if (mat[0, 0] == -1 || mat[n - 1, m - 1] == -1) {
            return 0;
        }

        // Queue to store the current cell
        Queue<(int, int)> q = new Queue<(int, int)>();
        q.Enqueue((0, 0));

        // Variable to store the number of ways
        int ways = 0;

        // Directions for moving right and down
        int[][] directions = new int[][] {
            new int[] { 1, 0 },
            new int[] { 0, 1 }
        };

        while (q.Count > 0) {
            var (i, j) = q.Dequeue();

            // If reached the bottom-right cell, increment ways
            if (i == n - 1 && j == m - 1) {
                ways++;
                continue;
            }

            // Explore adjacent cells (right and down)
            foreach (var dir in directions) {
                int ni = i + dir[0], nj = j + dir[1];

                // Check if within bounds and not blocked
                if (ni >= 0 && ni < n && nj >= 0 
                       && nj < m && mat[ni, nj] != -1) {
                  
                    q.Enqueue((ni, nj));
                }
            }
        }

        return ways;
    }

    static void Main() {

        int[,] mat = { { 0, 0, 0 },
                        { 0, -1, 0 },
                        { 0, 0, 0 } };

        Console.WriteLine(findWays(mat));
    }
}
JavaScript
// Javascript code to find the number of ways 
// in a maze with blocked cells using BFS

// Function to find the number of ways using BFS
function findWays(mat) {
    let n = mat.length, m = mat[0].length;

    // If starting or ending cell is blocked, return 0
    if (mat[0][0] === -1 || mat[n-1][m-1] === -1) {
        return 0;
    }

    // Queue to store the current cell and path count
    let q = [];
    q.push([0, 0]);

    // Variable to store the number of ways
    let ways = 0;

    // Directions for moving right and down
    let directions = [[1, 0], [0, 1]];

    while (q.length > 0) {
        let [i, j] = q.shift();

        // If reached the bottom-right cell, increment ways
        if (i === n-1 && j === m-1) {
            ways++;
            continue;
        }

        // Explore adjacent cells (right and down)
        for (let dir of directions) {
            let ni = i + dir[0];
            let nj = j + dir[1];

            // Check if within bounds and not blocked
            if (ni < n && nj < m && mat[ni][nj] !== -1) {
                q.push([ni, nj]);
            }
        }
    }

    return ways;
}

let mat = [
    [0, 0, 0],
    [0, -1, 0],
    [0, 0, 0]
];

console.log(findWays(mat));

Output
2

Time Complexity: O(n*m), as each cell is visited at most once, and there are at most 2 neighbors (right, down)
Auxiliary Space: O(n*m), due to the queue storing positions of grid cells during BFS traversal.


Next Article
Article Tags :
Practice Tags :

Similar Reads