05. Rat in a Maze
β GFG solution to the Rat in a Maze problem: find all possible paths from source to destination using backtracking and DFS technique. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Consider a rat placed at position (0, 0) in an n x n square matrix maze[][]
. The rat's goal is to reach the destination at position (n-1, n-1). The rat can move in four possible directions: 'U' (up), 'D' (down), 'L' (left), 'R' (right).
The matrix contains only two possible values:
0: A blocked cell through which the rat cannot travel.
1: A free cell that the rat can pass through.
Your task is to find all possible paths the rat can take to reach the destination, starting from (0, 0) and ending at (n-1, n-1), under the condition that the rat cannot revisit any cell along the same path. The rat can only move to adjacent cells that are within the bounds of the matrix and not blocked.
If no path exists, return an empty list.
Note: Return the final result vector in lexicographically smallest order.
π Examples
Example 1
Input: maze[][] = [[1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0], [0, 1, 1, 1]]
Output: ["DDRDRR", "DRDDRR"]
Explanation: The rat can reach the destination at (3, 3) from (0, 0) by two paths -
DRDDRR and DDRDRR, when printed in sorted order we get DDRDRR DRDDRR.
Example 2
Input: maze[][] = [[1, 0], [1, 0]]
Output: []
Explanation: No path exists as the destination cell (1, 1) is blocked.
Example 3
Input: maze[][] = [[1, 1, 1], [1, 0, 1], [1, 1, 1]]
Output: ["DDRR", "RRDD"]
Explanation: The rat has two possible paths to reach the destination: DDRR and RRDD.
π Constraints
$2 \le n \le 5$
$0 \le \text{maze}[i][j] \le 1$
β
My Approach
The optimal approach uses Backtracking with DFS (Depth-First Search) to explore all possible paths from source to destination:
Backtracking + DFS
Initial Check:
Verify if the starting cell
(0, 0)
and destination cell(n-1, n-1)
are both open (value = 1).If either is blocked, return an empty result immediately.
Mark as Visited:
Before exploring from a cell, mark it as visited by setting
maze[i][j] = 0
.This prevents the rat from revisiting the same cell in the current path.
Explore Four Directions:
Try all four directions in lexicographical order: D (Down), L (Left), R (Right), U (Up).
For each direction, check if the next cell is valid (within bounds and not blocked).
Recursively explore the next cell by appending the direction character to the current path.
Base Case - Destination Reached:
When the rat reaches
(n-1, n-1)
, add the current path string to the result list.
Backtrack:
After exploring all paths from the current cell, restore it by setting
maze[i][j] = 1
.This allows the cell to be used in other potential paths.
Return All Paths:
The result naturally maintains lexicographical order due to the direction exploration sequence.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(4^(nΒ²)), as in the worst case, we explore all four directions from each cell. The total number of cells is nΒ², and at each cell, we have up to 4 choices, leading to an exponential time complexity.
Expected Auxiliary Space Complexity: O(nΒ²), where the recursion stack can go as deep as nΒ² in the worst case (visiting all cells), and we modify the maze in-place for marking visited cells.
π§βπ» Code (C++)
class Solution {
public:
vector<string> ratInMaze(vector<vector<int>>& m) {
vector<string> res;
int n = m.size();
if (!m[0][0] || !m[n-1][n-1]) return res;
string p = "";
solve(0, 0, m, n, p, res);
return res;
}
void solve(int i, int j, vector<vector<int>>& m, int n, string p, vector<string>& res) {
if (i == n-1 && j == n-1) {
res.push_back(p);
return;
}
m[i][j] = 0;
if (i+1 < n && m[i+1][j]) solve(i+1, j, m, n, p+'D', res);
if (j-1 >= 0 && m[i][j-1]) solve(i, j-1, m, n, p+'L', res);
if (j+1 < n && m[i][j+1]) solve(i, j+1, m, n, p+'R', res);
if (i-1 >= 0 && m[i-1][j]) solve(i-1, j, m, n, p+'U', res);
m[i][j] = 1;
}
};
β Code (Java)
class Solution {
public ArrayList<String> ratInMaze(int[][] m) {
ArrayList<String> res = new ArrayList<>();
int n = m.length;
if (m[0][0] == 0 || m[n-1][n-1] == 0) return res;
solve(0, 0, m, n, "", res);
return res;
}
void solve(int i, int j, int[][] m, int n, String p, ArrayList<String> res) {
if (i == n-1 && j == n-1) {
res.add(p);
return;
}
m[i][j] = 0;
if (i+1 < n && m[i+1][j] == 1) solve(i+1, j, m, n, p+'D', res);
if (j-1 >= 0 && m[i][j-1] == 1) solve(i, j-1, m, n, p+'L', res);
if (j+1 < n && m[i][j+1] == 1) solve(i, j+1, m, n, p+'R', res);
if (i-1 >= 0 && m[i-1][j] == 1) solve(i-1, j, m, n, p+'U', res);
m[i][j] = 1;
}
}
π Code (Python)
class Solution:
def ratInMaze(self, m):
res = []
n = len(m)
if not m[0][0] or not m[n-1][n-1]: return res
self.solve(0, 0, m, n, "", res)
return res
def solve(self, i, j, m, n, p, res):
if i == n-1 and j == n-1:
res.append(p)
return
m[i][j] = 0
if i+1 < n and m[i+1][j]: self.solve(i+1, j, m, n, p+'D', res)
if j-1 >= 0 and m[i][j-1]: self.solve(i, j-1, m, n, p+'L', res)
if j+1 < n and m[i][j+1]: self.solve(i, j+1, m, n, p+'R', res)
if i-1 >= 0 and m[i-1][j]: self.solve(i-1, j, m, n, p+'U', res)
m[i][j] = 1
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated