Given a square binary grid mat of size n x n, a rat starts at the top-left cell (0, 0) and wants to reach the bottom-right cell (n - 1, n - 1).
1 is open — the rat may stand on it.0 is blocked — the rat may never enter it.The rat moves one step at a time in the four directions up (U), down (D), left (L), and right (R). It may travel only through open cells, and may not visit the same cell twice within a single path.
Return all valid paths from the source to the destination. Each path is the string of moves the rat takes to get there. If no path exists, return an empty list.
Input: mat = [[1,0,0,0],[1,1,0,1],[1,1,0,0],[0,1,1,1]] Output: ["DDRDRR", "DRDDRR"] Two trails reach the bottom-right corner: down-down-right-down-right-right and down-right-down-down-right-right.
Input: mat = [[1,0],[1,0]] Output: [] The destination cell (1,1) is blocked, so no path can reach it.
- 2 <= n <= 5 - mat[i][j] is either 0 or 1 - mat is a square grid of size n x n
Rat in a Maze is the classic first taste of backtracking: make a move, and if it leads nowhere, quietly undo it and try the next. Master the mark-and-unmark rhythm here and every grid and backtracking problem afterward starts to feel familiar.
In plain English: from cell (0, 0), walk only on open cells (value 1), never step on a cell already on your current trail, and record the moves — U, D, L, R — of every route that reaches (n-1, n-1).
Formally: given an n x n grid mat of 0s and 1s, return every string over {U, D, L, R} describing a simple path from (0, 0) to (n-1, n-1) that stays on cells equal to 1.
Worked example — n = 4
grid one valid trail: D D R D R R 1 0 0 0 (0,0) -> (1,0) -> (2,0) -> (2,1) -> (3,1) -> (3,2) -> (3,3) 1 1 0 1 1 1 0 0 start: move Down twice, Right, Down, Right, Right 0 1 1 1 reach: bottom-right corner OK
Both DDRDRR and DRDDRR reach the corner, so the answer is [DDRDRR, DRDDRR].
Naming the input guarantees before you code shows the interviewer you think in edge cases, not just the happy path.
“Is the grid always square, and can the start or destination cell be blocked?”
If either corner is blocked the answer is immediately empty — a one-line guard at the top.
“Are only the four orthogonal moves allowed, with no diagonals?”
Confirming this rules out sneaky diagonal shortcuts and fixes the move set.
“Can a cell be revisited within the same path?”
No — each path is simple, which is exactly what the visited marks enforce.
“Should the paths come back in lexicographic order?”
This decides whether we sort at the end or order our moves to get sorting for free.
Before I code, a few quick checks.
The grid is n by n, and I return an empty list if either corner is blocked — correct?
Movement is the four orthogonal directions, no diagonals, and a cell cannot repeat within one path?
And the paths should be lexicographically ordered — I will try directions as D, L, R, U to handle that.
Standing on a cell, your only state is where you are and which cells your current trail already occupies. Mark a cell when you step on it, unmark it when you leave, and that same cell is free to appear in a completely different path later.
enter (r,c): mark visited -> try 4 moves -> unmark (r,c) before returning
Check that the next cell is in-bounds, open (== 1), and unvisited before recursing into it. This kills dead branches at the door, so the search tree only ever holds partial trails that are still alive.
If you always try moves in the order D, L, R, U — which is alphabetical — the first complete path you finish is the lexicographically smallest, and every path after it is larger. No final sort needed.
D < L < R < U -> recurse in that order -> results emerge pre-sorted
| Brute force | Optimal | |
|---|---|---|
| Time | O(4^(n^2) · n^2) | O(4^(n^2)) |
| Space | O(n^4) | O(n^2) |
| Visited state | copy the whole set each step | mark on enter, unmark on leave |
| Ordering | sort at the end | ordered moves, sorted for free |
Both explore the same search tree; the optimal one just refuses to photocopy its notebook at every step. The full code for each is in the Approaches selector below.
Key takeaway
Backtracking is "choose, explore, un-choose." Carry a single shared record of the current trail, mark a cell on the way in and unmark it on the way out, and try directions alphabetically to get sorted output without sorting. This mark/unmark rhythm is the backbone of every grid-path, permutation, and N-Queens problem.
solve(r, c, path):
if (r, c) is destination: record path; return
mark (r, c) visited
for (dr, dc, ch) in [D, L, R, U]:
nr, nc = r + dr, c + dc
if in bounds and mat[nr][nc] == 1 and not visited: solve(nr, nc, path + ch)
unmark (r, c) visited