Approach

  Blog    |     January 27, 2026

To solve this problem, we need to find the shortest path from a starting point 'S' to an ending point 'E' in a grid while avoiding obstacles '#'. The grid consists of cells that can be empty ('.'), obstacles ('#'), the start ('S'), or the end ('E'). The movement is restricted to up, down, left, and right directions. The approach involves using Breadth-First Search (BFS) to explore the grid level by level, which ensures that the first time we reach the end point 'E', we have the shortest path. BFS is suitable here because it explores all neighboring cells before moving to the next level, making it efficient for finding the shortest path in an unweighted grid.

  1. Initialization: Locate the starting position 'S' and the ending position 'E' in the grid.
  2. BFS Setup: Use a queue to manage the cells to be explored. Each queue entry consists of the current cell's coordinates and the number of steps taken to reach it.
  3. Visited Tracking: Maintain a visited matrix to avoid revisiting cells and cycles.
  4. Direction Handling: Explore all four possible directions (up, down, left, right) from each cell.
  5. Termination Condition: If the end point 'E' is reached during BFS traversal, return the step count immediately. If the queue is exhausted without finding 'E', return -1.

Solution Code

from collections import deque
def min_steps(grid):
    n = len(grid)
    m = len(grid[0])
    start = None
    end = None
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 'S':
                start = (i, j)
            elif grid[i][j] == 'E':
                end = (i, j)
    if start is None or end is None:
        return -1
    visited = [[False] * m for _ in range(n)]
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
    queue = deque()
    queue.append((start[0], start[1], 0))
    visited[start[0]][start[1]] = True
    while queue:
        r, c, steps = queue.popleft()
        if (r, c) == end:
            return steps
        for dr, dc in directions:
            nr, nc = r + dr, c + dc
            if 0 <= nr < n and 0 <= nc < m:
                if not visited[nr][nc] and grid[nr][nc] != '#':
                    visited[nr][nc] = True
                    queue.append((nr, nc, steps + 1))
    return -1

Explanation

  1. Initialization: The grid dimensions are determined, and the positions of 'S' and 'E' are located by scanning each cell.
  2. BFS Initialization: The BFS starts from the 'S' position with an initial step count of 0. The visited matrix marks 'S' as visited.
  3. BFS Execution: For each cell dequeued, check if it is 'E'. If yes, return the current step count. Otherwise, explore all four adjacent cells. If an adjacent cell is within bounds, not visited, and not an obstacle, it is marked as visited and enqueued with an incremented step count.
  4. Termination: If the queue is exhausted without finding 'E', return -1, indicating no valid path exists.

This approach efficiently explores the grid level by level, ensuring the shortest path is found if it exists, leveraging BFS properties for unweighted grids. The time complexity is O(nm) as each cell is processed at most once. The space complexity is also O(nm) due to the visited matrix and queue storage.


Request an On-site Audit / Inquiry

SSL Secured Inquiry