2Brute2Best
🔥0

Rat in a Maze

Medium·GeeksforGeeksBasic Anchor
GeeksforGeeks
30-Second Mental ModelBacktracking → Grid / path search (DFS with mark and unmark)
Complexity:O(n² · 3^(n²))→O(3^(n²) + A · n²)
Key Insight

Keep one grid for the whole search. When the rat enters a cell, mark it. When every move from that cell has been tried, unmark it on the way out. The marks then always show exactly the current route. Trying the moves in the order D, L, R, U makes the routes come out sorted.

Core Validity Invariant

At every call, a cell is marked exactly when the current route stands on it. Marks are added on the way in and removed on the way out, so the grid always matches the route.

01

Problem

A rat starts in the top-left cell of an n × n maze. It wants to reach the bottom-right cell.

Each cell is either open (1) or a wall (0). The rat moves one cell at a time: D (down), L (left), R (right) or U (up). It can only step on open cells, and it may not step on the same cell twice in one route.

Return every route as a string of move letters, in alphabetical order. If there is no route, return an empty list. A wall at the start or at the end means there is no route.

In the examples, (row, col) counts rows and columns from 0, starting at the top-left.

Input

maze, an n × n grid of 0s and 1s. The cell in row r and column c is maze[r][c].

Output

A list of strings. Each string is one route, written as its moves. The list is in alphabetical order. The list is empty if there is no route.

Example 1
Input: maze = [[1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0], [0, 1, 1, 1]]
Output: ["DDRDRR", "DRDDRR"]

There are two routes. Both pass through (2,1), (3,1) and (3,2). DDRDRR goes through (2,0), and DRDDRR goes through (1,1) instead.

Example 2
Input: maze = [[1, 0], [0, 1]]
Output: []

Both first moves, D and R, lead into a wall, so the rat is stuck at the start.

Example 3
Input: maze = [[1, 1], [1, 1]]
Output: ["DR", "RD"]

Every cell is open. The rat can go down then right, or right then down.

Constraints
  • • The maze is n × n, with n at least 2.
  • • Each cell is 0 (wall) or 1 (open).
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    The rule says a route may not step on the same cell twice. Is that a rule about one route, or about the whole search?

  2. 2.

    After one route fails, which cells should the rat be able to use again for the next route?

  3. 3.

    Two routes can pass through the same cell. If that cell stays blocked after the first visit, what happens to the second route?

  4. 4.

    In which order should the four moves be tried so the routes come out alphabetically, without a sort?

  5. 5.

    Can a route walk past the end cell and come back to it?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceEach call gets its own copy of the visited grid; sort the answers at the endO(n² · 3^(n²))O(n⁴)
OptimalOne grid for the whole search: mark a cell on entry, unmark it on exit; try D, L, R, UO(3^(n²) + A · n²)O(n²)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “from the top-left to the bottom-right”A route from one cell to another in a grid. Each step is one move to a neighbouring cell.
  • “return every route”We need every choice explored, not a yes or no. Each finished route is one answer.
  • “cannot step on a cell twice”The rule is about one route. Many routes can use the same cell, one after another.
  • “in alphabetical order”The routes are strings of letters. The order the moves are tried decides the order of the answers.
Grid cell to cell+all routes+mark on entry, unmark on exit+fixed move order→Backtracking → Grid / path search (DFS with mark and unmark)

The mark belongs to the route, not to the search. Mark the cell on the way in, and unmark it on the way out, so each route sees exactly the cells it has used. This differs from the graph-traversal habit of one permanent visited set, which hides every route that shares a cell. Word Search uses the same mark and unmark on a letter board, but it stops at the first match.

10

Don't make this mistake

Pattern confusion: a permanent visited set from graph traversal
✗ seen[r][c] = true; // marked on the way in, and never cleared
✓ seen[r][c] = true; // ... moves ... seen[r][c] = false; // unmarked on the way out

In graph traversal a visited node is never visited again. Here a cell can be used by many routes. Trace the example: the first route DDRDRR marks (2,1), (3,1) and (3,2). The search also goes up to (1,1), finds a dead end, and never clears (1,1). When it returns to (1,0) and tries R, the cell (1,1) is still marked, so the second route DRDDRR is lost. The output is only ["DDRDRR"].

Trusting the order the moves were tried in
✗ const char mv[] = {'U', 'R', 'D', 'L'}; // and return the answers without sorting
✓ const char mv[] = {'D', 'L', 'R', 'U'}; // alphabetical order, so no sort is needed

Trying U, R, D, L first finds DRDDRR before DDRDRR. If the answers are returned as they are, the output is ["DRDDRR", "DDRDRR"], which is the wrong order. The routes only come out sorted when the moves are tried in alphabetical order, or when the answers are sorted.

Forgetting to check the start and end cells
✗ // no check: the search starts at (0,0) even when it is a wall
✓ if (maze[0][0] == 0 || maze[n - 1][n - 1] == 0) return {};

On the maze [[0, 1], [1, 1]] the start is a wall. The search would still enter (0,0), move D to (1,0), then R to (1,1), and return ["DR"]. The correct answer is an empty list, because the rat cannot start in a wall.

11

Want to implement this?

Write it yourself on GeeksforGeeks, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Backtracking translate into production architectures and low-level memory mechanics.