Rat in a Maze Problem in DSA Python - Time & Space Complexity
We want to understand how the time needed to solve the Rat in a Maze problem changes as the maze size grows.
Specifically, how does the number of steps the algorithm takes grow when the maze gets bigger?
Analyze the time complexity of the following code snippet.
def solve_maze(maze, x, y, solution):
n = len(maze)
if x == n - 1 and y == n - 1:
solution[x][y] = 1
return True
if 0 <= x < n and 0 <= y < n and maze[x][y] == 1:
solution[x][y] = 1
if solve_maze(maze, x + 1, y, solution):
return True
if solve_maze(maze, x, y + 1, solution):
return True
solution[x][y] = 0
return False
return False
This code tries to find a path from the top-left to the bottom-right of a maze using backtracking.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls exploring each cell in the maze.
- How many times: Potentially every cell is visited multiple times in different paths.
As the maze size grows, the number of possible paths grows very fast because the rat can move right or down at each step.
| Input Size (n) | Approx. Operations |
|---|---|
| 2 | Up to 22*2 = 16 |
| 3 | Up to 22*3 = 64 |
| 4 | Up to 22*4 = 256 |
Pattern observation: The operations grow exponentially as the maze size increases.
Time Complexity: O(2^(2n))
This means the time needed can grow very fast, roughly quadrupling for each unit increase in maze size n.
[X] Wrong: "The algorithm only checks one path, so it runs in linear time."
[OK] Correct: The algorithm tries many possible paths using recursion, so it explores many combinations, not just one.
Understanding this problem helps you think about how recursive backtracking explores many options, which is useful for many puzzles and pathfinding tasks.
"What if the rat could move in all four directions instead of just right and down? How would the time complexity change?"
Practice
Rat in a Maze problem?Solution
Step 1: Understand the problem objective
The Rat in a Maze problem asks to find a path from the start cell (usually top-left) to the destination cell (usually bottom-right) in a maze represented by a grid.Step 2: Identify the correct goal
The goal is to find a valid path through open cells, avoiding obstacles, not just counting walls or distances.Final Answer:
Find a path from the start to the destination in a maze -> Option AQuick Check:
Goal = Find path [OK]
- Confusing pathfinding with counting obstacles
- Thinking the problem is about shortest path always
- Assuming the maze is always square
Solution
Step 1: Check boundary conditions first
We must first ensure x and y are within valid indices (>= 0) before accessing maze[x][y] to avoid errors.Step 2: Check if the cell is open (value 1)
After confirming indices, check if maze[x][y] == 1 to confirm the cell is open for movement.Final Answer:
if x >= 0 and y >= 0 and maze[x][y] == 1: -> Option AQuick Check:
Check bounds before access [OK]
- Checking maze[x][y] before verifying indices
- Using 'or' instead of 'and' in conditions
- Checking for maze[x][y] != 1 instead of == 1
maze = [
[1, 0, 0, 0],
[1, 1, 0, 1],
[0, 1, 0, 0],
[1, 1, 1, 1]
]
solution = [[0]*4 for _ in range(4)]
def solve_maze(x, y):
if x == 3 and y == 3:
solution[x][y] = 1
return True
if 0 <= x < 4 and 0 <= y < 4 and maze[x][y] == 1:
solution[x][y] = 1
if solve_maze(x + 1, y):
return True
if solve_maze(x, y + 1):
return True
solution[x][y] = 0
return False
return False
solve_maze(0, 0)
print(solution)Solution
Step 1: Trace the recursive path from (0,0) to (3,3)
The function tries moving down first, then right. It marks cells in solution as 1 when moving forward and backtracks by resetting to 0 if dead end.Step 2: Follow the path and update solution matrix
Path found is (0,0) -> (1,0) -> (1,1) -> (2,1) -> (3,1) -> (3,2) -> (3,3). These cells are marked 1 in solution.Final Answer:
[[1, 0, 0, 0], [1, 1, 0, 0], [0, 1, 0, 0], [0, 1, 1, 1]] -> Option CQuick Check:
Path marked correctly in solution [OK]
- Confusing backtracking reset steps
- Assuming right move tried before down
- Not marking the destination cell
def solve_maze(x, y):
if x == len(maze) - 1 and y == len(maze[0]) - 1:
solution[x][y] = 1
return True
if x >= 0 and y >= 0 and maze[x][y] == 1:
solution[x][y] = 1
if solve_maze(x + 1, y):
return True
if solve_maze(x, y + 1):
return True
solution[x][y] = 0
return False
return FalseSolution
Step 1: Analyze boundary checks in the condition
The condition 'if x >= 0 and y >= 0 and maze[x][y] == 1' misses checking if x and y are less than maze size, risking index errors.Step 2: Confirm base case and backtracking correctness
The base case marks destination cell and returns True. Backtracking resets solution[x][y] to 0 correctly. Maze obstacles are checked.Final Answer:
The boundary check misses upper limits for x and y -> Option BQuick Check:
Check both lower and upper bounds [OK]
- Forgetting to check upper bounds causes errors
- Assuming base case is wrong when it is correct
- Ignoring backtracking step
Solution
Step 1: Understand standard algorithm behavior
The standard algorithm returns True immediately after finding the first path, stopping further search.Step 2: Modify to find all paths
Instead of returning True immediately, store the current path in a list and continue exploring other paths by backtracking to find all possible routes.Final Answer:
Store each valid path in a list and continue searching after backtracking -> Option DQuick Check:
Collect all paths by continuing search [OK]
- Stopping after first path found
- Not storing paths properly
- Confusing BFS queue with backtracking recursion
Ready to prove it?
Pass the test and this pattern moves unknown
