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).

**Example:

**Input: mat[][] = [[1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0], [0, 1, 1, 1]]

1

**Output: ["DDRDRR", "DRDDRR"]
**Explanation: The possible paths are: DDRDRR, DRDDRR

2

[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] = 1

Function 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 result

if 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.