#1091 Shortest Path in Binary Matrix
the problem
In plain words
In an n×n grid of 0s (open) and 1s (blocked), find the length of the shortest clear path from the top-left to the bottom-right, moving in 8 directions. Length counts cells. Return -1 if none exists.
in grid = [[0,1],[1,0]]
out 2
One diagonal step: 2 cells.
in grid = [[0,0,0],[1,1,0],[1,1,0]]
out 4
in grid = [[1,0,0],[1,1,0],[1,1,0]]
out -1
The start is blocked.
- 1 ≤ n ≤ 100
- grid[i][j] is 0 or 1
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternBFS shortest path (unweighted)
Every move costs 1, so BFS finds the shortest path: the first time BFS pops the target, that's the answer.
solutions
From brute force to optimal
Try every simple path; keep the shortest; prune paths already as long as the best.
- Mark the cell on the path, recurse in 8 directions, unmark on return.
- At the target, update best.
The number of simple paths in a grid grows exponentially with n²; pruning doesn't change the worst case.
onPath grid and recursion depth up to n².
class Solution { private static final int[][] DIRS = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; private int best; /** Try every simple path with DFS + backtracking and keep the shortest. Exponential. */ public int shortestPathBinaryMatrix(int[][] grid) { int n = grid.length; if (grid[0][0] != 0 || grid[n - 1][n - 1] != 0) return -1; best = Integer.MAX_VALUE; boolean[][] onPath = new boolean[n][n]; onPath[0][0] = true; explore(grid, 0, 0, 1, onPath); return best == Integer.MAX_VALUE ? -1 : best; } private void explore(int[][] g, int r, int c, int len, boolean[][] onPath) { int n = g.length; if (len >= best) return; // can't beat what we already have if (r == n - 1 && c == n - 1) { best = len; return; } for (int[] d : DIRS) { int nr = r + d[0], nc = c + d[1]; if (nr < 0 || nc < 0 || nr >= n || nc >= n || g[nr][nc] != 0 || onPath[nr][nc]) continue; onPath[nr][nc] = true; explore(g, nr, nc, len + 1, onPath); onPath[nr][nc] = false; // undo: other paths may use this cell } }}BFS with 8 directions, storing the path length in each cell when first discovered.
- If start or end is blocked → -1.
- len[0][0] = 1; BFS.
- When the target is polled, return its length.
Each of the n² cells is enqueued at most once; 8 neighbours each.
The length grid and the queue.
class Solution { private static final int[][] DIRS = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; public int shortestPathBinaryMatrix(int[][] grid) { int n = grid.length; if (grid[0][0] != 0 || grid[n - 1][n - 1] != 0) return -1; int[][] len = new int[n][n]; // cells on the path so far; 0 = unseen Deque<int[]> queue = new ArrayDeque<>(); queue.offer(new int[] {0, 0}); len[0][0] = 1; // the path length counts cells, so the start alone is 1 while (!queue.isEmpty()) { int[] cell = queue.poll(); int r = cell[0], c = cell[1]; if (r == n - 1 && c == n - 1) return len[r][c]; // first arrival = shortest for (int[] d : DIRS) { int nr = r + d[0], nc = c + d[1]; if (nr < 0 || nc < 0 || nr >= n || nc >= n || grid[nr][nc] != 0 || len[nr][nc] != 0) continue; len[nr][nc] = len[r][c] + 1; queue.offer(new int[] {nr, nc}); } } return -1; }}Dry run
in the room
How to say it in the interview
talk track
- Check both corners for 1 before anything else.
- Clarify that length counts cells, so the start alone is 1.
traps
- Using 4 directions — diagonals are allowed here.
- Returning steps (cells − 1).
what they ask next
Follow-ups
Faster in practice?
A* with the Chebyshev distance max(|dr|, |dc|) as the heuristic explores fewer cells; worst case is the same.
before you submit
Edge cases to test
- n = 1 with grid [[0]] → 1 (the path is the start cell itself).
- Start or end blocked → -1 before any search.
- Diagonal squeezes count: [[0,1],[1,0]] → 2.
practise next
Similar problems
- #1730Shortest Path to Get FoodMediumin GraphsLeetCode Premium
- #994Rotting OrangesMediumin Graphs
- #2290Minimum Obstacle Removal to Reach CornerHardin Shortest Paths