Shortest Path in a Grid (BFS)

Problem

A grid has 0 for open cells and 1 for walls. You start at the top-left cell and want to reach the bottom-right cell. You can move up, down, left or right (not diagonally) through open cells. Print the smallest number of moves, or -1 if there is no path.

Constraints

  • 1 <= r, c <= 100

Examples

Input

3 3
0 0 0
1 1 0
0 0 0

Output

4

Solutions

Best approachTime O(r * c)Space O(r * c)

Breadth-first search explores the grid in rings: first all cells at distance 1, then distance 2, and so on. So the first time it reaches a cell, the distance is the shortest one. A queue gives this order.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process a grid.
 * Input   : r and c, then r rows of c numbers (0 or 1).
 * Output  : The fewest moves or -1.
 * Approach: Breadth-first search.
 * Time    : O(r * c)
 * Space   : O(r * c)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static int solve(int[][] m) {
        int rows = m.length;
        int cols = m[0].length;

        // Step 1: If the start or the end is a wall, there is no path.
        if (m[0][0] == 1 || m[rows - 1][cols - 1] == 1) {
            return -1;
        }

        // Step 2: distance[i][j] = moves needed to reach the cell. -1 means: not visited yet.
        int[][] distance = new int[rows][cols];
        for (int[] row : distance) {
            java.util.Arrays.fill(row, -1);
        }

        // Step 3: A queue keeps the cells to visit. BFS visits cells in the order of their distance.
        java.util.ArrayDeque<int[]> queue = new java.util.ArrayDeque<>();
        queue.add(new int[] {0, 0});
        distance[0][0] = 0;
        int[] stepRow = {1, -1, 0, 0};
        int[] stepCol = {0, 0, 1, -1};

        while (!queue.isEmpty()) {
            int[] cell = queue.poll();

            // Step 4: The first time we reach the end cell, we have the shortest distance.
            if (cell[0] == rows - 1 && cell[1] == cols - 1) {
                return distance[cell[0]][cell[1]];
            }

            // Step 5: Try the four neighbours. Visit open cells that were not visited before.
            for (int d = 0; d < 4; d++) {
                int nextRow = cell[0] + stepRow[d];
                int nextCol = cell[1] + stepCol[d];
                if (nextRow >= 0 && nextRow < rows && nextCol >= 0 && nextCol < cols
                        && m[nextRow][nextCol] == 0 && distance[nextRow][nextCol] == -1) {
                    distance[nextRow][nextCol] = distance[cell[0]][cell[1]] + 1;
                    queue.add(new int[] {nextRow, nextCol});
                }
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int rows = scanner.nextInt();
        int cols = scanner.nextInt();
        int[][] m = new int[rows][cols];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                m[i][j] = scanner.nextInt();
            }
        }
        System.out.println(solve(m));
    }
}
Hints (2)
  1. Which data structure gives first-in, first-out order?
  2. Why is the first arrival the shortest?