Logo for ammarahmed.ca
Medium
Jan 13, 2026
#graph
#bfs

1730. Shortest Path To Get Food

You are starving and you want to eat food as quickly as possible. You want to find the shortest path to arrive at a food cell.

You are given an m x n character matrix, grid, of these different types of cells:

  • '*' is your location. There is exactly one '*' cell.
    • '#' is a food cell. There may be multiple food cells.
      • 'O' is free space, and you can travel through these cells.
        • 'X' is an obstacle, and you cannot travel through these cells.

          Return the length of the shortest path for you to reach any food cell. If there is no path for you to reach food, return -1.

          Example 1:

          1Input: grid = [["X","X","X","X","X","X"],["X","*","O","O","O","X"],["X","O","O","#","O","X"],["X","X","X","X","X","X"]] 2Output: 3 3Explanation: It takes 3 steps to reach the food.

          Example 2:

          1Input: grid = [["X","X","X","X","X"],["X","*","X","O","X"],["X","O","X","#","X"],["X","X","X","X","X"]] 2Output: -1 3Explanation: It is not possible to reach the food.

          Example 3:

          1Input: grid = [["X","X","X","X","X","X","X","X"],["X","*","O","X","O","#","O","X"],["X","O","O","X","O","O","X","X"],["X","O","O","O","O","#","O","X"],["X","X","X","X","X","X","X","X"]] 2Output: 6 3Explanation: There can be multiple food cells. It only takes 6 steps to reach the bottom food.

          Example 4:

          1Input: grid = [["O","*"],["#","O"]] 2Output: 2

          Example 5:

          1Input: grid = [["X","*"],["#","X"]] 2Output: -1

          Notes

          Intuition

          Finding the shortest path in an unweighted grid is a classic BFS problem. BFS explores all cells at distance k before any cell at distance k+1, guaranteeing the first food cell reached is the closest.

          Implementation

          First, locate the starting position (*). Initialize a queue with the start coordinate and path length 0, plus a visited set. Process cells level by level: for each cell, check its four neighbors. Skip if visited or blocked (X). If it's food (#), return the current path length + 1. Otherwise, add to visited and queue with incremented path.

          Edge-cases

          If BFS completes without finding food, return -1 (no reachable food). The visited set prevents revisiting cells and infinite loops.

          • Time: O(m * n) — each cell visited at most once
            • Space: O(m * n) — visited set and queue

              Complexity

              Solution

              1from typing import List, Tuple 2from collections import deque 3 4class Solution: 5 def neighbours(self, coord: Tuple[int, int], grid: List[List[str]]) -> List[Tuple[int, int]]: 6 dirs = [(0, 1), (0, -1), (-1, 0), (1, 0)] 7 result = [] 8 i, j = coord 9 for di, dj in dirs: 10 ni, nj = i + di, j + dj 11 if ni < 0 or ni >= len(grid) or nj < 0 or nj >= len(grid[0]): 12 continue 13 result.append((ni, nj)) 14 return result 15 def shortestPath(self, grid: List[List[str]]) -> int: 16 # Step 1: Find start coordinate 17 start = (-1, -1) 18 for i in range(len(grid)): 19 for j in range(len(grid[i])): 20 if grid[i][j] == "*": 21 start = (i, j) 22 break 23 24 # Step 2: BFS to find shortest path with visited set 25 visited = set([start]) 26 q = deque([(start, 0)]) 27 while q: 28 curr, path = q.popleft() 29 for n in self.neighbours(curr, grid): 30 ni, nj = n 31 if n in visited or grid[ni][nj] == "X": 32 continue 33 if grid[ni][nj] == "#": 34 return path + 1 35 visited.add(n) 36 q.append((n, path + 1)) 37 return -1 38 39if __name__ == "__main__": 40 # Include one-off tests here or debugging logic that can be run by running this file 41 # e.g. print(solution.two_sum([1, 2, 3, 4], 3)) 42 solution = Solution() 43