Rat in a Maze (original) (raw)
Given a square binary matrix **mat[][] representing a maze. Find all possible paths from (0, 0) to (n-1, n-1).
- A rat starts at the top-left corner (0,0) and needs to reach the bottom-right corner (n-1, n-1).
- The rat can move in four directions: Up (U), Down (D), Left (L), Right (R).
- A rat cannot visit the same cell more than once in a path.
- 1 represents an open cell (rat can visit), and 0 represents a blocked cell (rat cannot visit).
- If multiple paths exist, return them in lexicographically sorted order otherwise If no path exists, return empty list.
**Example:
**Input: mat[][] = [[1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0], [0, 1, 1, 1]]
**Output: ["DDRDRR", "DRDDRR"]
**Explanation: The possible paths are: DDRDRR, DRDDRR
[Approach] Using Recursion and Backtracking
The idea is to explore all possible paths from the source to the destination in the maze. We recursively build each path, store it when the destination is reached, and backtrack to explore alternative routes. To avoid revisiting cells in the same path, we mark a cell as visited during exploration and unmark it during backtracking.
C++ `
#include #include #include #include using namespace std;
// Directions: Down, Left, Right, Up string dir = "DLRU"; int dr[4] = {1, 0, 0, -1}; int dc[4] = {0, -1, 1, 0};
// Check if a cell is valid (inside the maze and open) bool isValid(int r, int c, int n, vector<vector>& maze) { return r >= 0 && c >= 0 && r < n && c < n && maze[r][c]; }
// Function to find all valid paths void findPath(int r, int c, vector<vector>& maze, string& path, vector& res) { int n = maze.size();
// If destination is reached, store the path
if (r == n - 1 && c == n - 1) {
res.push_back(path);
return;
}
// Mark current cell as visited
maze[r][c] = 0;
for (int i = 0; i < 4; i++) {
int nr = r + dr[i], nc = c + dc[i];
if (isValid(nr, nc, n, maze)) {
path.push_back(dir[i]);
// Move to the next cell recursively
findPath(nr, nc, maze, path, res);
// Backtrack
path.pop_back();
}
}
// Unmark current cell
maze[r][c] = 1; }
// Function to find all paths and return them vector ratInMaze(vector<vector>& maze) { vector result; int n = maze.size(); string path = "";
if (maze[0][0] == 1 && maze[n - 1][n - 1] == 1) {
// Start from (0,0)
findPath(0, 0, maze, path, result);
}
// Sort results lexicographically
sort(result.begin(), result.end());
return result;}
int main() { vector<vector> maze = { {1, 0, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 0}, {0, 1, 1, 1} };
vector<string> result = ratInMaze(maze);
for (auto p : result) {
cout << p << " ";
}
return 0;}
Java
import java.util.ArrayList; import java.util.Collections;
class GFG {
// Directions: Down, Left, Right, Up
static String dir = "DLRU";
static int[] dr = {1, 0, 0, -1};
static int[] dc = {0, -1, 1, 0};
// Check if a cell is valid (inside the maze and open)
static boolean isValid(int r, int c, int n, int[][] maze) {
return r >= 0 && c >= 0 && r < n && c < n && maze[r][c] == 1;
}
// Function to find all valid paths
static void findPath(int r, int c, int[][] maze, StringBuilder path,
ArrayList<String> res) {
int n = maze.length;
// If destination is reached, store the path
if (r == n - 1 && c == n - 1) {
res.add(path.toString());
return;
}
// Mark current cell as visited
maze[r][c] = 0;
for (int i = 0; i < 4; i++) {
int nr = r + dr[i], nc = c + dc[i];
if (isValid(nr, nc, n, maze)) {
path.append(dir.charAt(i));
// Move to the next cell recursively
findPath(nr, nc, maze, path, res);
// Backtrack
path.deleteCharAt(path.length() - 1);
}
}
// Unmark current cell
maze[r][c] = 1;
}
// Function to find all paths and return them
static ArrayList<String> ratInMaze(int[][] maze) {
ArrayList<String> result = new ArrayList<>();
int n = maze.length;
StringBuilder path = new StringBuilder();
if (maze[0][0] == 1 && maze[n - 1][n - 1] == 1) {
// Start from (0,0)
findPath(0, 0, maze, path, result);
}
// Sort results lexicographically
Collections.sort(result);
return result;
}
public static void main(String[] args) {
int[][] maze = {
{1, 0, 0, 0},
{1, 1, 0, 1},
{1, 1, 0, 0},
{0, 1, 1, 1}
};
ArrayList<String> result = ratInMaze(maze);
for (String p : result) {
System.out.print(p + " ");
}
}}
Python
Directions: Down, Left, Right, Up
dir = "DLRU" dr = [1, 0, 0, -1] dc = [0, -1, 1, 0]
Check if a cell is valid (inside the maze and open)
def isValid(r, c, n, maze): return r >= 0 and c >= 0 and r < n and c < n and maze[r][c] == 1
Function to find all valid paths
def findPath(r, c, maze, path, res): n = len(maze)
# If destination is reached, store the path
if r == n - 1 and c == n - 1:
res.append("".join(path))
return
# Mark current cell as visited
maze[r][c] = 0
for i in range(4):
nr, nc = r + dr[i], c + dc[i]
if isValid(nr, nc, n, maze):
path.append(dir[i])
# Move to the next cell recursively
findPath(nr, nc, maze, path, res)
# Backtrack
path.pop()
# Unmark current cell
maze[r][c] = 1Function to find all paths and return them
def ratInMaze(maze): result = [] n = len(maze) path = []
if maze[0][0] == 1 and maze[n - 1][n - 1] == 1:
# Start from (0,0)
findPath(0, 0, maze, path, result)
# Sort results lexicographically
result.sort()
return resultif name == "main": maze = [ [1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0], [0, 1, 1, 1] ]
result = ratInMaze(maze)
for p in result:
print(p, end=" ")C#
using System; using System.Collections.Generic;
class GFG {
// Directions: Down, Left, Right, Up
static string dir = "DLRU";
static int[] dr = { 1, 0, 0, -1 };
static int[] dc = { 0, -1, 1, 0 };
// Check if a cell is valid (inside the maze and open)
static bool isValid(int r, int c, int n, int[,] maze) {
return r >= 0 && c >= 0 && r < n && c < n && maze[r, c] == 1;
}
// Function to find all valid paths
static void findPath(int r, int c, int[,] maze, List<char> path, List<string> res) {
int n = maze.GetLength(0);
// If destination is reached, store the path
if (r == n - 1 && c == n - 1) {
res.Add(new string(path.ToArray()));
return;
}
// Mark current cell as visited
maze[r, c] = 0;
for (int i = 0; i < 4; i++) {
int nr = r + dr[i], nc = c + dc[i];
if (isValid(nr, nc, n, maze)) {
path.Add(dir[i]);
// Move to the next cell recursively
findPath(nr, nc, maze, path, res);
// Backtrack
path.RemoveAt(path.Count - 1);
}
}
// Unmark current cell
maze[r, c] = 1;
}
// Function to find all paths and return them
static List<string> ratInMaze(int[,] maze) {
List<string> result = new List<string>();
int n = maze.GetLength(0);
List<char> path = new List<char>();
if (maze[0, 0] == 1 && maze[n - 1, n - 1] == 1)
{
// Start from (0,0)
findPath(0, 0, maze, path, result);
}
// Sort results lexicographically
result.Sort();
return result;
}
public static void Main(string[] args) {
int[,] maze = {
{1, 0, 0, 0},
{1, 1, 0, 1},
{1, 1, 0, 0},
{0, 1, 1, 1}
};
List<string> result = ratInMaze(maze);
foreach (string p in result) {
Console.Write(p + " ");
}
}}
JavaScript
// Directions: Down, Left, Right, Up const dir = "DLRU"; const dr = [1, 0, 0, -1]; const dc = [0, -1, 1, 0];
// Check if a cell is valid (inside the maze and open) function isValid(r, c, n, maze) { return r >= 0 && c >= 0 && r < n && c < n && maze[r][c] === 1; }
// Function to find all valid paths function findPath(r, c, maze, path, res) { const n = maze.length;
// If destination is reached, store the path
if (r === n - 1 && c === n - 1) {
res.push(path);
return;
}
// Mark current cell as visited
maze[r][c] = 0;
for (let i = 0; i < 4; i++) {
const nr = r + dr[i], nc = c + dc[i];
if (isValid(nr, nc, n, maze)) {
path += dir[i];
// Move to the next cell recursively
findPath(nr, nc, maze, path, res);
// Backtrack
path = path.slice(0, -1);
}
}
// Unmark current cell
maze[r][c] = 1;}
// Function to find all paths and return them function ratInMaze(maze) { let result = []; const n = maze.length; let path = "";
if (maze[0][0] === 1 && maze[n - 1][n - 1] === 1) {
// Start from (0,0)
findPath(0, 0, maze, path, result);
}
// Sort results lexicographically
result.sort();
return result;}
// Driver Code const maze = [ [1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0], [0, 1, 1, 1] ];
const result = ratInMaze(maze);
console.log(result.join(" "));
`
**Time Complexity: O(4n*n), because on every cell we have to try 4 different directions.
**Auxiliary Space: O(n2), Maximum Depth of the recursion tree.

