Shortest path in a Binary Maze

• Difficulty Level : Hard
• Last Updated : 09 Jun, 2021

Given a MxN matrix where each element can either be 0 or 1. We need to find the shortest path between a given source cell to a destination cell. The path can only be created out of a cell if its value is 1.
Expected time complexity is O(MN).
For example –

```Input:
mat[ROW][COL]  = {{1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{1, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
{1, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
{0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{1, 1, 1, 0, 1, 1, 1, 0, 1, 0 },
{1, 0, 1, 1, 1, 1, 0, 1, 0, 0 },
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{1, 1, 0, 0, 0, 0, 1, 0, 0, 1 }};
Source = {0, 0};
Destination = {3, 4};

Output:
Shortest Path is 11 ```

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

The idea is inspired from Lee algorithm and uses BFS.

1. We start from the source cell and calls BFS procedure.
2. We maintain a queue to store the coordinates of the matrix and initialize it with the source cell.
3. We also maintain a Boolean array visited of same size as our input matrix and initialize all its elements to false.
1. We LOOP till queue is not empty
2. Dequeue front cell from the queue
3. Return if the destination coordinates have reached.
4. For each of its four adjacent cells, if the value is 1 and they are not visited yet, we enqueue it in the queue and also mark them as visited.

Note that BFS works here because it doesn’t consider a single path at once. It considers all the paths starting from the source and moves ahead one unit in all those paths at the same time which makes sure that the first time when the destination is visited, it is the shortest path.
Below is the implementation of the idea –

C++

 `// C++ program to find the shortest path between` `// a given source cell to a destination cell.` `#include ` `using` `namespace` `std;` `#define ROW 9` `#define COL 10`   `//To store matrix cell coordinates` `struct` `Point` `{` `    ``int` `x;` `    ``int` `y;` `};`   `// A Data Structure for queue used in BFS` `struct` `queueNode` `{` `    ``Point pt;  ``// The coordinates of a cell` `    ``int` `dist;  ``// cell's distance of from the source` `};`   `// check whether given cell (row, col) is a valid` `// cell or not.` `bool` `isValid(``int` `row, ``int` `col)` `{` `    ``// return true if row number and column number` `    ``// is in range` `    ``return` `(row >= 0) && (row < ROW) &&` `           ``(col >= 0) && (col < COL);` `}`   `// These arrays are used to get row and column` `// numbers of 4 neighbours of a given cell` `int` `rowNum[] = {-1, 0, 0, 1};` `int` `colNum[] = {0, -1, 1, 0};`   `// function to find the shortest path between` `// a given source cell to a destination cell.` `int` `BFS(``int` `mat[][COL], Point src, Point dest)` `{` `    ``// check source and destination cell` `    ``// of the matrix have value 1` `    ``if` `(!mat[src.x][src.y] || !mat[dest.x][dest.y])` `        ``return` `-1;`   `    ``bool` `visited[ROW][COL];` `    ``memset``(visited, ``false``, ``sizeof` `visited);` `    `  `    ``// Mark the source cell as visited` `    ``visited[src.x][src.y] = ``true``;`   `    ``// Create a queue for BFS` `    ``queue q;` `    `  `    ``// Distance of source cell is 0` `    ``queueNode s = {src, 0};` `    ``q.push(s);  ``// Enqueue source cell`   `    ``// Do a BFS starting from source cell` `    ``while` `(!q.empty())` `    ``{` `        ``queueNode curr = q.front();` `        ``Point pt = curr.pt;`   `        ``// If we have reached the destination cell,` `        ``// we are done` `        ``if` `(pt.x == dest.x && pt.y == dest.y)` `            ``return` `curr.dist;`   `        ``// Otherwise dequeue the front ` `        ``// cell in the queue` `        ``// and enqueue its adjacent cells` `        ``q.pop();`   `        ``for` `(``int` `i = 0; i < 4; i++)` `        ``{` `            ``int` `row = pt.x + rowNum[i];` `            ``int` `col = pt.y + colNum[i];` `            `  `            ``// if adjacent cell is valid, has path and` `            ``// not visited yet, enqueue it.` `            ``if` `(isValid(row, col) && mat[row][col] && ` `               ``!visited[row][col])` `            ``{` `                ``// mark cell as visited and enqueue it` `                ``visited[row][col] = ``true``;` `                ``queueNode Adjcell = { {row, col},` `                                      ``curr.dist + 1 };` `                ``q.push(Adjcell);` `            ``}` `        ``}` `    ``}`   `    ``// Return -1 if destination cannot be reached` `    ``return` `-1;` `}`   `// Driver program to test above function` `int` `main()` `{` `    ``int` `mat[ROW][COL] =` `    ``{` `        ``{ 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },` `        ``{ 1, 0, 1, 0, 1, 1, 1, 0, 1, 1 },` `        ``{ 1, 1, 1, 0, 1, 1, 0, 1, 0, 1 },` `        ``{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },` `        ``{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 0 },` `        ``{ 1, 0, 1, 1, 1, 1, 0, 1, 0, 0 },` `        ``{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },` `        ``{ 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },` `        ``{ 1, 1, 0, 0, 0, 0, 1, 0, 0, 1 }` `    ``};`   `    ``Point source = {0, 0};` `    ``Point dest = {3, 4};`   `    ``int` `dist = BFS(mat, source, dest);`   `    ``if` `(dist != -1)` `        ``cout << ``"Shortest Path is "` `<< dist ;` `    ``else` `        ``cout << ``"Shortest Path doesn't exist"``;`   `    ``return` `0;` `}`

Java

 `// Java program to find the shortest ` `// path between a given source cell ` `// to a destination cell.` `import` `java.util.*;`   `class` `GFG ` `{` `static` `int` `ROW = ``9``;` `static` `int` `COL = ``10``;`   `// To store matrix cell coordinates` `static` `class` `Point` `{` `    ``int` `x;` `    ``int` `y;`   `    ``public` `Point(``int` `x, ``int` `y)` `    ``{` `        ``this``.x = x;` `        ``this``.y = y;` `    ``}` `};`   `// A Data Structure for queue used in BFS` `static` `class` `queueNode` `{` `    ``Point pt; ``// The coordinates of a cell` `    ``int` `dist; ``// cell's distance of from the source`   `    ``public` `queueNode(Point pt, ``int` `dist)` `    ``{` `        ``this``.pt = pt;` `        ``this``.dist = dist;` `    ``}` `};`   `// check whether given cell (row, col) ` `// is a valid cell or not.` `static` `boolean` `isValid(``int` `row, ``int` `col)` `{` `    ``// return true if row number and ` `    ``// column number is in range` `    ``return` `(row >= ``0``) && (row < ROW) &&` `           ``(col >= ``0``) && (col < COL);` `}`   `// These arrays are used to get row and column` `// numbers of 4 neighbours of a given cell` `static` `int` `rowNum[] = {-``1``, ``0``, ``0``, ``1``};` `static` `int` `colNum[] = {``0``, -``1``, ``1``, ``0``};`   `// function to find the shortest path between` `// a given source cell to a destination cell.` `static` `int` `BFS(``int` `mat[][], Point src,` `                            ``Point dest)` `{` `    ``// check source and destination cell` `    ``// of the matrix have value 1` `    ``if` `(mat[src.x][src.y] != ``1` `|| ` `        ``mat[dest.x][dest.y] != ``1``)` `        ``return` `-``1``;`   `    ``boolean` `[][]visited = ``new` `boolean``[ROW][COL];` `    `  `    ``// Mark the source cell as visited` `    ``visited[src.x][src.y] = ``true``;`   `    ``// Create a queue for BFS` `    ``Queue q = ``new` `LinkedList<>();` `    `  `    ``// Distance of source cell is 0` `    ``queueNode s = ``new` `queueNode(src, ``0``);` `    ``q.add(s); ``// Enqueue source cell`   `    ``// Do a BFS starting from source cell` `    ``while` `(!q.isEmpty())` `    ``{` `        ``queueNode curr = q.peek();` `        ``Point pt = curr.pt;`   `        ``// If we have reached the destination cell,` `        ``// we are done` `        ``if` `(pt.x == dest.x && pt.y == dest.y)` `            ``return` `curr.dist;`   `        ``// Otherwise dequeue the front cell ` `        ``// in the queue and enqueue` `        ``// its adjacent cells` `        ``q.remove();`   `        ``for` `(``int` `i = ``0``; i < ``4``; i++)` `        ``{` `            ``int` `row = pt.x + rowNum[i];` `            ``int` `col = pt.y + colNum[i];` `            `  `            ``// if adjacent cell is valid, has path ` `            ``// and not visited yet, enqueue it.` `            ``if` `(isValid(row, col) && ` `                    ``mat[row][col] == ``1` `&& ` `                    ``!visited[row][col])` `            ``{` `                ``// mark cell as visited and enqueue it` `                ``visited[row][col] = ``true``;` `                ``queueNode Adjcell = ``new` `queueNode` `                             ``(``new` `Point(row, col),` `                                   ``curr.dist + ``1` `);` `                ``q.add(Adjcell);` `            ``}` `        ``}` `    ``}`   `    ``// Return -1 if destination cannot be reached` `    ``return` `-``1``;` `}`   `// Driver Code` `public` `static` `void` `main(String[] args) ` `{` `    ``int` `mat[][] = {{ ``1``, ``0``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``1` `},` `                   ``{ ``1``, ``0``, ``1``, ``0``, ``1``, ``1``, ``1``, ``0``, ``1``, ``1` `},` `                   ``{ ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``0``, ``1``, ``0``, ``1` `},` `                   ``{ ``0``, ``0``, ``0``, ``0``, ``1``, ``0``, ``0``, ``0``, ``0``, ``1` `},` `                   ``{ ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``1``, ``0``, ``1``, ``0` `},` `                   ``{ ``1``, ``0``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1``, ``0``, ``0` `},` `                   ``{ ``1``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``1` `},` `                   ``{ ``1``, ``0``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``1` `},` `                   ``{ ``1``, ``1``, ``0``, ``0``, ``0``, ``0``, ``1``, ``0``, ``0``, ``1` `}};`   `    ``Point source = ``new` `Point(``0``, ``0``);` `    ``Point dest = ``new` `Point(``3``, ``4``);`   `    ``int` `dist = BFS(mat, source, dest);`   `    ``if` `(dist != -``1``)` `        ``System.out.println(``"Shortest Path is "` `+ dist);` `    ``else` `        ``System.out.println(``"Shortest Path doesn't exist"``);` `    ``}` `}`   `// This code is contributed by PrinciRaj1992`

Python

 `# Python program to find the shortest` `# path between a given source cell ` `# to a destination cell.`   `from` `collections ``import` `deque` `ROW ``=` `9` `COL ``=` `10`   `# To store matrix cell coordinates` `class` `Point:` `    ``def` `__init__(``self``,x: ``int``, y: ``int``):` `        ``self``.x ``=` `x` `        ``self``.y ``=` `y`   `# A data structure for queue used in BFS` `class` `queueNode:` `    ``def` `__init__(``self``,pt: Point, dist: ``int``):` `        ``self``.pt ``=` `pt  ``# The coordinates of the cell` `        ``self``.dist ``=` `dist  ``# Cell's distance from the source`   `# Check whether given cell(row,col)` `# is a valid cell or not` `def` `isValid(row: ``int``, col: ``int``):` `    ``return` `(row >``=` `0``) ``and` `(row < ROW) ``and` `                   ``(col >``=` `0``) ``and` `(col < COL)`   `# These arrays are used to get row and column ` `# numbers of 4 neighbours of a given cell ` `rowNum ``=` `[``-``1``, ``0``, ``0``, ``1``]` `colNum ``=` `[``0``, ``-``1``, ``1``, ``0``]`   `# Function to find the shortest path between ` `# a given source cell to a destination cell. ` `def` `BFS(mat, src: Point, dest: Point):` `    `  `    ``# check source and destination cell ` `    ``# of the matrix have value 1 ` `    ``if` `mat[src.x][src.y]!``=``1` `or` `mat[dest.x][dest.y]!``=``1``:` `        ``return` `-``1` `    `  `    ``visited ``=` `[[``False` `for` `i ``in` `range``(COL)] ` `                       ``for` `j ``in` `range``(ROW)]` `    `  `    ``# Mark the source cell as visited ` `    ``visited[src.x][src.y] ``=` `True` `    `  `    ``# Create a queue for BFS ` `    ``q ``=` `deque()` `    `  `    ``# Distance of source cell is 0` `    ``s ``=` `queueNode(src,``0``)` `    ``q.append(s) ``#  Enqueue source cell` `    `  `    ``# Do a BFS starting from source cell ` `    ``while` `q:`   `        ``curr ``=` `q.popleft() ``# Dequeue the front cell` `        `  `        ``# If we have reached the destination cell, ` `        ``# we are done ` `        ``pt ``=` `curr.pt` `        ``if` `pt.x ``=``=` `dest.x ``and` `pt.y ``=``=` `dest.y:` `            ``return` `curr.dist` `        `  `        ``# Otherwise enqueue its adjacent cells ` `        ``for` `i ``in` `range``(``4``):` `            ``row ``=` `pt.x ``+` `rowNum[i]` `            ``col ``=` `pt.y ``+` `colNum[i]` `            `  `            ``# if adjacent cell is valid, has path  ` `            ``# and not visited yet, enqueue it.` `            ``if` `(isValid(row,col) ``and` `               ``mat[row][col] ``=``=` `1` `and` `                ``not` `visited[row][col]):` `                ``visited[row][col] ``=` `True` `                ``Adjcell ``=` `queueNode(Point(row,col),` `                                    ``curr.dist``+``1``)` `                ``q.append(Adjcell)` `    `  `    ``# Return -1 if destination cannot be reached ` `    ``return` `-``1`   `# Driver code` `def` `main():` `    ``mat ``=` `[[ ``1``, ``0``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``1` `],` `           ``[ ``1``, ``0``, ``1``, ``0``, ``1``, ``1``, ``1``, ``0``, ``1``, ``1` `], ` `           ``[ ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``0``, ``1``, ``0``, ``1` `], ` `           ``[ ``0``, ``0``, ``0``, ``0``, ``1``, ``0``, ``0``, ``0``, ``0``, ``1` `], ` `           ``[ ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``1``, ``0``, ``1``, ``0` `], ` `           ``[ ``1``, ``0``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1``, ``0``, ``0` `], ` `           ``[ ``1``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``1` `], ` `           ``[ ``1``, ``0``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1``, ``1``, ``1` `], ` `           ``[ ``1``, ``1``, ``0``, ``0``, ``0``, ``0``, ``1``, ``0``, ``0``, ``1` `]]` `    ``source ``=` `Point(``0``,``0``)` `    ``dest ``=` `Point(``3``,``4``)` `    `  `    ``dist ``=` `BFS(mat,source,dest)` `    `  `    ``if` `dist!``=``-``1``:` `        ``print``(``"Shortest Path is"``,dist)` `    ``else``:` `        ``print``(``"Shortest Path doesn't exist"``)` `main()`   `# This code is contributed by stutipathak31jan`

C#

 `// C# program to find the shortest ` `// path between a given source cell ` `// to a destination cell.` `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG ` `{` `static` `int` `ROW = 9;` `static` `int` `COL = 10;`   `// To store matrix cell coordinates` `public` `class` `Point` `{` `    ``public` `int` `x;` `    ``public` `int` `y;`   `    ``public` `Point(``int` `x, ``int` `y)` `    ``{` `        ``this``.x = x;` `        ``this``.y = y;` `    ``}` `};`   `// A Data Structure for queue used in BFS` `public` `class` `queueNode` `{` `    ``// The coordinates of a cell` `    ``public` `Point pt; ` `    `  `    ``// cell's distance of from the source` `    ``public` `int` `dist; `   `    ``public` `queueNode(Point pt, ``int` `dist)` `    ``{` `        ``this``.pt = pt;` `        ``this``.dist = dist;` `    ``}` `};`   `// check whether given cell (row, col) ` `// is a valid cell or not.` `static` `bool` `isValid(``int` `row, ``int` `col)` `{` `    ``// return true if row number and ` `    ``// column number is in range` `    ``return` `(row >= 0) && (row < ROW) &&` `           ``(col >= 0) && (col < COL);` `}`   `// These arrays are used to get row and column` `// numbers of 4 neighbours of a given cell` `static` `int` `[]rowNum = {-1, 0, 0, 1};` `static` `int` `[]colNum = {0, -1, 1, 0};`   `// function to find the shortest path between` `// a given source cell to a destination cell.` `static` `int` `BFS(``int` `[,]mat, Point src,` `                           ``Point dest)` `{` `    ``// check source and destination cell` `    ``// of the matrix have value 1` `    ``if` `(mat[src.x, src.y] != 1 || ` `        ``mat[dest.x, dest.y] != 1)` `        ``return` `-1;`   `    ``bool` `[,]visited = ``new` `bool``[ROW, COL];` `    `  `    ``// Mark the source cell as visited` `    ``visited[src.x, src.y] = ``true``;`   `    ``// Create a queue for BFS` `    ``Queue q = ``new` `Queue();` `    `  `    ``// Distance of source cell is 0` `    ``queueNode s = ``new` `queueNode(src, 0);` `    ``q.Enqueue(s); ``// Enqueue source cell`   `    ``// Do a BFS starting from source cell` `    ``while` `(q.Count != 0)` `    ``{` `        ``queueNode curr = q.Peek();` `        ``Point pt = curr.pt;`   `        ``// If we have reached the destination cell,` `        ``// we are done` `        ``if` `(pt.x == dest.x && pt.y == dest.y)` `            ``return` `curr.dist;`   `        ``// Otherwise dequeue the front cell ` `        ``// in the queue and enqueue` `        ``// its adjacent cells` `        ``q.Dequeue();`   `        ``for` `(``int` `i = 0; i < 4; i++)` `        ``{` `            ``int` `row = pt.x + rowNum[i];` `            ``int` `col = pt.y + colNum[i];` `            `  `            ``// if adjacent cell is valid, has path ` `            ``// and not visited yet, enqueue it.` `            ``if` `(isValid(row, col) && ` `                    ``mat[row, col] == 1 && ` `               ``!visited[row, col])` `            ``{` `                ``// mark cell as visited and enqueue it` `                ``visited[row, col] = ``true``;` `                ``queueNode Adjcell = ``new` `queueNode` `                           ``(``new` `Point(row, col),` `                                ``curr.dist + 1 );` `                ``q.Enqueue(Adjcell);` `            ``}` `        ``}` `    ``}`   `    ``// Return -1 if destination cannot be reached` `    ``return` `-1;` `}`   `// Driver Code` `public` `static` `void` `Main(String[] args) ` `{` `    ``int` `[,]mat = {{ 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },` `                  ``{ 1, 0, 1, 0, 1, 1, 1, 0, 1, 1 },` `                   ``{ 1, 1, 1, 0, 1, 1, 0, 1, 0, 1 },` `                  ``{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },` `                  ``{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 0 },` `                  ``{ 1, 0, 1, 1, 1, 1, 0, 1, 0, 0 },` `                  ``{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },` `                  ``{ 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },` `                  ``{ 1, 1, 0, 0, 0, 0, 1, 0, 0, 1 }};`   `    ``Point source = ``new` `Point(0, 0);` `    ``Point dest = ``new` `Point(3, 4);`   `    ``int` `dist = BFS(mat, source, dest);`   `    ``if` `(dist != -1)` `        ``Console.WriteLine(``"Shortest Path is "` `+ dist);` `    ``else` `        ``Console.WriteLine(``"Shortest Path doesn't exist"``);` `    ``}` `}`   `// This code is contributed by PrinciRaj1992`

Output :

`Shortest Path is 11`