Quick Info

Category: Backtracking
Time Complexity: O(2^(n*n))
Space Complexity: O(n*n)
Input Type: Maze

Rat in a Maze

Description

The Rat in a Maze is a classic backtracking problem where a rat needs to find a path from the source (top-left corner) to the destination (bottom-right corner) in a maze. The maze is represented as a binary matrix where 1 represents a valid path and 0 represents a blocked path.

How It Works

  1. Start from the source cell (0,0)
  2. The rat can move in four directions: right, down, left, or up
  3. For each move:
    • Check if the move is valid (within bounds and not blocked)
    • Mark the current cell as part of the path
    • Recursively try to reach the destination from the new position
    • If the recursive call fails, backtrack by unmarking the current cell
  4. If the destination is reached, a path is found
  5. If no direction leads to the destination, return false

Visualization

Click on cells to toggle walls, then click Start

Implementation


def solve_maze(maze):
    n = len(maze)
    # Solution matrix initialized with 0's
    sol = [[0 for _ in range(n)] for _ in range(n)]
    
    if solve_maze_util(maze, 0, 0, sol, n):
        return sol
    return None

def is_safe(maze, x, y, n):
    return (x >= 0 and x < n and 
            y >= 0 and y < n and 
            maze[x][y] == 1)

def solve_maze_util(maze, x, y, sol, n):
    # If (x, y) is the destination, return True
    if x == n-1 and y == n-1:
        sol[x][y] = 1
        return True
    
    if is_safe(maze, x, y, n):
        # Mark current cell as part of solution path
        sol[x][y] = 1
        
        # Try moving right
        if solve_maze_util(maze, x, y+1, sol, n):
            return True
        
        # Try moving down
        if solve_maze_util(maze, x+1, y, sol, n):
            return True
        
        # Try moving left
        if solve_maze_util(maze, x, y-1, sol, n):
            return True
        
        # Try moving up
        if solve_maze_util(maze, x-1, y, sol, n):
            return True
        
        # If no direction works, backtrack
        sol[x][y] = 0
        return False
    
    return False
                                    

class RatMaze {
private:
    bool isSafe(vector<vector<int>>& maze, int x, int y, int n) {
        return (x >= 0 && x < n && 
                y >= 0 && y < n && 
                maze[x][y] == 1);
    }
    
    bool solveMazeUtil(vector<vector<int>>& maze, 
                       int x, int y, 
                       vector<vector<int>>& sol, 
                       int n) {
        // Base case: destination reached
        if (x == n-1 && y == n-1) {
            sol[x][y] = 1;
            return true;
        }
        
        if (isSafe(maze, x, y, n)) {
            sol[x][y] = 1;
            
            // Try moving right
            if (solveMazeUtil(maze, x, y+1, sol, n))
                return true;
            
            // Try moving down
            if (solveMazeUtil(maze, x+1, y, sol, n))
                return true;
            
            // Try moving left
            if (solveMazeUtil(maze, x, y-1, sol, n))
                return true;
            
            // Try moving up
            if (solveMazeUtil(maze, x-1, y, sol, n))
                return true;
            
            // Backtrack
            sol[x][y] = 0;
            return false;
        }
        
        return false;
    }
    
public:
    vector<vector<int>> solveMaze(vector<vector<int>>& maze) {
        int n = maze.size();
        vector<vector<int>> sol(n, vector<int>(n, 0));
        
        if (solveMazeUtil(maze, 0, 0, sol, n))
            return sol;
            
        return vector<vector<int>>();
    }
};
                                    

public class RatMaze {
    private bool IsSafe(int[,] maze, int x, int y, int n) {
        return (x >= 0 && x < n && 
                y >= 0 && y < n && 
                maze[x,y] == 1);
    }
    
    private bool SolveMazeUtil(int[,] maze, int x, int y, 
                              int[,] sol, int n) {
        // Base case: destination reached
        if (x == n-1 && y == n-1) {
            sol[x,y] = 1;
            return true;
        }
        
        if (IsSafe(maze, x, y, n)) {
            sol[x,y] = 1;
            
            // Try moving right
            if (SolveMazeUtil(maze, x, y+1, sol, n))
                return true;
            
            // Try moving down
            if (SolveMazeUtil(maze, x+1, y, sol, n))
                return true;
            
            // Try moving left
            if (SolveMazeUtil(maze, x, y-1, sol, n))
                return true;
            
            // Try moving up
            if (SolveMazeUtil(maze, x-1, y, sol, n))
                return true;
            
            // Backtrack
            sol[x,y] = 0;
            return false;
        }
        
        return false;
    }
    
    public int[,] SolveMaze(int[,] maze) {
        int n = (int)Math.Sqrt(maze.Length);
        int[,] sol = new int[n,n];
        
        if (SolveMazeUtil(maze, 0, 0, sol, n))
            return sol;
            
        return null;
    }
}
                                    

Complexity Analysis

Time Complexity

The time complexity of the Rat in a Maze algorithm is O(2^(n*n)), where n is the size of the maze. This is because:

  • At each cell, we have up to 4 possible moves
  • We may need to explore every possible path
  • The maximum path length is n*n cells
  • Each cell needs to be checked for validity (O(1))

Space Complexity

The space complexity is O(n*n), where n is the maze size. This includes:

  • The solution matrix to track the path
  • The recursion stack (maximum depth n*n)
  • The original maze matrix

Advantages and Disadvantages

Advantages

  • Guaranteed to find a path if one exists
  • Simple implementation using recursion
  • Can be modified to find all possible paths
  • Works with any maze configuration
  • Memory efficient for small mazes

Disadvantages

  • Exponential time complexity
  • May be slow for large mazes
  • Not optimal for finding shortest path
  • Stack overflow possible for very large mazes
  • Performance degrades with maze complexity