CMD Guide
HomeDSACompany Practice

medium Shortest Path in Binary Matrix

Problem Statement

Given a matrix of size m x n, return the length of the shortest path from the top-left corner (0,0) to the bottom-right corner (N-1, N-1). If there is no such path, the output should be -1.

Follow the rules below while calculating the shortest path.

Examples

  1. Example 1:
[[0, 0, 0], 
 [0, 1, 0], 
 [0, 0, 0]]
  1. Example 2:
[[0, 1, 0], 
 [0, 0, 0], 
 [0, 1, 0]]
  1. Example 3:
[1, 1, 1], 
 [0, 1, 1], 
 [0, 0, 0]]

Try it yourself

Try solving this question here:

🎯 STRICT STANDOUT — Shortest Path in Binary Matrix — problem

1. Why / judgment

Unweighted shortest path on grid with 8-neighbor moves and obstacles (1s). BFS is mandatory for unweighted shortest path — DFS/Dijkstra without 0-weights is wrong or slower. Clear start/end blocked → -1. Path length counts cells (or edges — lock problem definition; page uses steps as cells in path).

2. Big-O derivation (K11)

BFS O(m·n) time/space worst visit all cells.
DFS not optimal. A* optional heuristic.
0-1 BFS not needed (uniform cost).

3. Pattern + when-NOT (K12)

Name: GRID BFS 8-CONNECTED

Recognition: shortest path binary matrix clear cells.

When-NOT: Weighted cells → Dijkstra. 4-connected only → fewer edges. Need path reconstruct → parent pointers. Multiple queries → precompute different structure.

4. Edge hand-run (K13)

1×1 [[0]] → 1; [[1]] → -1.
start blocked grid[0][0]==1 → -1.
fully open n×n → n (diagonal) if 8-connected.
page [[0,0,0],[0,1,0],[0,0,0]] → 4.

5. Interviewer follow-ups (model answers)

Q1. Why BFS not DFS?
A: First time you reach end in BFS is min steps on unweighted graph.

Q2. Mark visited when push or pop?
A: When push — prevents queue explosion.

Q3. Diagonal blocked corners?
A: Problem allows diagonal into 0 cells; no corner-cut rule usually (check statement).

6. Short drills

Drill: hand BFS distances on 3×3 with center block.
Drill: implement 8 dirs array.
✅ Solution Shortest Path in Binary Matrix

Problem Statement

Given a matrix of size m x n, return the length of the shortest path from the top-left corner (0,0) to the bottom-right corner (N-1, N-1). If there is no such path, the output should be -1.

Follow the rules below while calculating the shortest path.

  • You can move horizontally, vertically, and diagonally to adjacent cells.
  • The visited cell should be 0.
  • The path length is counted as the number of steps taken.

Examples

  1. Example 1:
  • Input:
[[0, 0, 0], 
 [0, 1, 0], 
 [0, 0, 0]]
  • Expected Output: 4
  • Justification: The shortest path is (0, 0) -> (1, 0) -> (2, 1) -> (2, 2), totaling 4 steps.
  1. Example 2:
  • Input:
[[0, 1, 0], 
 [0, 0, 0], 
 [0, 1, 0]]
  • Expected Output: 3
  • Justification: The shortest path is (0, 0) -> (1, 1) -> (2, 2), totaling 3 steps.
  1. Example 3:
  • Input:
[1, 1, 1], 
 [0, 1, 1], 
 [0, 0, 0]]
  • Expected Output: -1
  • Justification: The top-left cell can't be visited, as its value is 1. So, it returns -1.

Solution

To solve this problem, we'll use the Breadth-First Search (BFS) algorithm. BFS is suitable for finding the shortest path in a graph, and here, our matrix can be viewed as a graph where each cell is a node connected to its 8 adjacent cells.

BFS explores the neighbors of a node before moving to the next level, ensuring that the first time we reach the destination, it's via the shortest path. The algorithm will be implemented using a queue to keep track of cells to visit and their distance from the start. We'll also use a way to mark visited cells to avoid revisiting them. This approach is effective because it systematically explores paths from the start and guarantees the shortest path due to the nature of BFS.

Step-by-step algorithm

  1. Initialization:

    • Check if the start (0,0) or end (N-1, N-1) cells are blocked. If so, return -1.
    • Initialize the queue with the starting cell (0,0) and its path length (1).
    • Set up the visited matrix, marking the start cell as visited.
    • Define directions for the 8 possible moves.
  2. BFS Loop:

    • While the queue is not empty:
      • Dequeue the first element (current cell and its path length).
      • Check if the current cell is the destination (N-1, N-1). If so, return its path length.
      • For each direction in directions:
        • Calculate the coordinates of the adjacent cell.
        • Check if the move is valid (cell is within bounds, not blocked, and not visited).
        • If valid, mark the cell as visited, and enqueue it with an incremented path length.
  3. No Path Found:

    • If the BFS loop completes without finding the destination, return -1.

Algorithm Walkthrough

Let's consider the Input:

[[0, 0, 0], 
 [0, 1, 0], 
 [0, 0, 0]]
Image
Image
  • Initialization: Start from (0,0) with path length 1. queue = [(0, 0, 1)], where (0, 0) represents the (row, col) of the matrix, and 1 represents the shortest path length till the current cell. visited[0][0] = true.

  • Step 1: Pop (0, 0, 1). Check all 8 directions:

    • Right (0,1): Valid and unvisited. Enqueue (0,1,2).
    • Down (1,0): Valid and unvisited. Enqueue (1,0,2).
    • Down-right (1,1): Blocked.
    • Update queue to [(0,1,2), (1,0,2)].
  • Step 2: Pop (0, 1, 2). Check all 8 directions:

    • Right (0,2): Valid and unvisited. Enqueue (0,2,3).
    • Down-right (1, 2): Valid and unvisited. Enqueue (1,2,3)
    • Update queue to [(1,0,2), (0,2,3), (1, 2, 3)].
  • Step 3: Pop (1, 0, 2). Check all 8 directions:

    • Down (2,0): Valid and unvisited. Enqueue (2,0,3).
    • Down-right (2,1): Valid and unvisited. Enqueue (2,1,3).
    • Update queue to [(0,2,3), (1, 2, 3), (2,0,3), (2, 1, 3)].
  • Step 4: Pop (0, 2, 3). Check all 8 directions:

    • All adjacent nodes are visited.
    • Update queue to [(1, 2, 3), (2,0,3), (2, 1, 3)].
  • Step 5: Pop (1, 2, 3). Check all 8 directions:

    • Down (2,2): Valid and unvisited. Enqueue (2,2,4).
    • Update queue to [(2,0,3), (2, 1, 3), (2, 2, 4)].
  • Step 6: Pop (2, 0, 3). Check all 8 directions:

    • All adjacent nodes are visited.
    • Update queue to [(2, 1, 3), (2, 2, 4)].
  • Step 7: Pop (2, 1, 3). Check all 8 directions:

    • All adjacent nodes are visited.
  • Step 8: Pop (2, 2, 4). This is the destination cell.

  • Return the path length 4 as it's the shortest path to the destination.

Code

java
import java.util.LinkedList;
import java.util.Queue;

public class Solution {

  // Define eight possible directions to move: up, down, left, right, and diagonally
  private static final int[][] DIRECTIONS = new int[][] {
    { 1, 0 },
    { 0, 1 },
    { 1, 1 },
    { -1, 0 },
    { 0, -1 },
    { -1, -1 },
    { 1, -1 },
    { -1, 1 },
  };

  public int shortestPathBinaryMatrix(int[][] grid) {
    int N = grid.length; // Get the size of the grid (assuming it's a square grid).
    if (grid[0][0] == 1 || grid[N - 1][N - 1] == 1) return -1; // Check if start or end is blocked.

    boolean[][] visited = new boolean[N][N]; // Create a boolean array to keep track of visited cells.
    Queue<int[]> queue = new LinkedList<>(); // Create a queue to perform breadth-first search.
    queue.add(new int[] { 0, 0, 1 }); // Add the starting cell (row, column, and path length).
    visited[0][0] = true; // Mark the starting cell as visited.

    while (!queue.isEmpty()) {
      int[] current = queue.poll(); // Get the current cell from the queue.
      int row = current[0], col = current[1], path = current[2]; // Extract row, column, and path length.

      if (row == N - 1 && col == N - 1) return path; // Check if we reached the destination.

      // Explore all eight possible directions from the current cell.
      for (int[] direction : DIRECTIONS) {
        int newRow = row + direction[0], newCol = col + direction[1];

        // Check if the new position is within the grid boundaries and not visited.
        if (
          newRow >= 0 &&
          newRow < N &&
          newCol >= 0 &&
          newCol < N &&
          grid[newRow][newCol] == 0 &&
          !visited[newRow][newCol]
        ) {
          queue.add(new int[] { newRow, newCol, path + 1 }); // Add the new cell to the queue with an increased path length.
          visited[newRow][newCol] = true; // Mark the new cell as visited.
        }
      }
    }
    return -1; // No path found.
  }

  public static void main(String[] args) {
    Solution solution = new Solution();
    // Example 1
    int[][] grid1 = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };
    System.out.println(
      "Example 1: " + solution.shortestPathBinaryMatrix(grid1)
    );

    // Example 2
    int[][] grid2 = { { 0, 1, 0 }, { 0, 0, 0 }, { 0, 1, 0 } };
    System.out.println(
      "Example 2: " + solution.shortestPathBinaryMatrix(grid2)
    );

    // Example 3
    int[][] grid3 = { { 1, 1, 1 }, { 0, 1, 1 }, { 0, 0, 0 } };
    System.out.println(
      "Example 3: " + solution.shortestPathBinaryMatrix(grid3)
    );
  }
}

Complexity Analysis

Time Complexity

The time complexity of the algorithm is O(N x M), where N is total number of rows, and M is total number of columns in the matrix.

The code uses a breadth-first search (BFS) approach to find the shortest path in the binary matrix. In the worst case, the BFS will visit each cell once. Therefore, the time complexity is O(N x M), where N x M is the size of the grid.

Space Complexity

The space complexity of the algorithm is O(N x M).

The visited array is of size N x M, which requires O(N x M) space to store the visited status of each cell. The queue used for BFS can have at most N x M cells in it at any point. Therefore, the space complexity is also O(N x M).

🎯 STRICT STANDOUT — Solution Shortest Path in Binary Matrix

1. Why / judgment

Unweighted grid (each step cost 1) with 8-neighborhood -> classic BFS for shortest path in hops. Only walk cells value 0. Answer is number of cells in the path (start counts as 1). If start or end is 1, return -1. Dijkstra unnecessary (unit weights); DFS finds some path not shortest.

2. Big-O derivation (K11)

n x n cells; each enqueued at most once -> O(n^2) time, O(n^2) queue/visited.
8 neighbors constant.
[[0,0,0],[0,1,0],[0,0,0]] -> path length 4.
Blocked corner -> -1 in O(1) check.
BFS layers expand by hop; first touch of end is minimal hops.

3. Pattern + when-NOT (K12)

Name: GRID BFS (8-CONNECTED, UNIT COST)

Recognition: shortest path in unweighted binary grid; diagonal moves allowed.

When-NOT: Weighted cells -> Dijkstra/0-1 BFS. 4-connected only -> change neighbor deltas. Need path reconstruction -> parent pointers, still BFS.

4. Edge hand-run (K13)

1x1 [[0]]->1; [[1]]->-1
All zeros n=2 -> 2
Visit mark on enqueue to avoid multi-queue bloat.

5. Interviewer follow-ups (model answers)

Q1. Why BFS not DFS?
A: Unit edge weights: first time BFS reaches the end is shortest; DFS can take detours.

Q2. Is answer cells or edges?
A: Cells in path — example path of 4 cells for n=3 clear route.

Q3. Why mark visited when pushing?
A: Prevents the same cell being queued many times from different parents.

6. Short drills

Drill: [[0,1],[1,0]] -> 2 (diagonal)
Drill: prove 8-dir can shortcut 4-dir paths.
🧩 Pattern · Matrix

Recognize it: Grid traversal / rotation / in-place marking → index arithmetic, or DFS/BFS over cells.

▶ Visualize this problem (step it, predict each fork)
⛶ Open this problem debugger in explore mode
🤖 Don't fully get this? Learn it with Claude

Stuck on Shortest Path in Binary Matrix? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Shortest Path in Binary Matrix** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Shortest Path in Binary Matrix** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Shortest Path in Binary Matrix**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Shortest Path in Binary Matrix**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes