You are starving and you want to eat food as quickly as possible. You want to find the shortest path to arrive at any 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.
You can travel to any adjacent cell north, east, south, or west of your current location if there is not an obstacle.
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:

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

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

Input: 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"]] Output: 6 Explanation: There can be multiple food cells. It only takes 6 steps to reach the bottom food.
Example 4:
Input: grid = [["O","*"],["#","O"]] Output: 2
Example 5:
Input: grid = [["X","*"],["#","X"]] Output: -1
Constraints:
m == grid.lengthn == grid[i].length1 <= m, n <= 200grid[row][col]is'*','X','O', or'#'.- The
gridcontains exactly one'*'.
獲取食物的最短路徑。
你現在很餓,想要盡快找東西吃。你需要找到最短的路徑到達一個食物所在的格子。
給定一個 m x n 的字符矩陣 grid ,包含下列不同類型的格子:
'*' 是你的位置。矩陣中有且只有一個 '*' 格子。 '#' 是食物。矩陣中可能存在多個食物。 'O' 是空地,你可以穿過這些格子。 'X' 是障礙,你不可以穿過這些格子。返回你到任意食物的最短路徑的長度。 如果不存在你到任意食物的路徑,返回 -1。
這是一道帶有障礙物的 flood fill 類型的題。給了唯一的起點,用 X 表示,請你返回一個找到食物的最短距離。在矩陣里做搜索,如果要找最短距離,往往是 BFS。
我們還是創建一個 queue,將起點放入 queue 中;同時我們需要一個與 input 矩陣同樣大小的二維數組 visited 記錄每個點是否被訪問過。接着我們從起點開始遍歷矩陣中每個有效的點。無效的點(障礙)是用 X 表示的,如果遇到了 X 則跳過不處理即可。我們需要關注的點是在矩陣范圍內且沒有被訪問過的點。訪問過之后,則將他放入 queue 接着往下找這些點自己的鄰居節點。因為對於每個點來說你並不知道他最后找到食物是在哪個方向上,所以記錄 step 的方式也跟一般 BFS 的題稍有區別。
時間O(mn)
空間O(mn)
Java實現
1 class Solution { 2 int[][] DIRS = { { 0, -1 }, { 0, 1 }, { 1, 0 }, { -1, 0 } }; 3 4 public int getFood(char[][] grid) { 5 int m = grid.length; 6 int n = grid[0].length; 7 Queue<int[]> queue = new LinkedList<>(); 8 for (int i = 0; i < m; i++) { 9 for (int j = 0; j < n; j++) { 10 if (grid[i][j] == '*') { 11 queue.offer(new int[] { i, j }); 12 break; 13 } 14 } 15 } 16 boolean[][] visited = new boolean[m][n]; 17 18 int step = 0; 19 while (!queue.isEmpty()) { 20 int size = queue.size(); 21 for (int i = 0; i < size; i++) { 22 int[] cur = queue.poll(); 23 int x = cur[0]; 24 int y = cur[1]; 25 if (grid[x][y] == '#') { 26 return step; 27 } 28 for (int[] dir : DIRS) { 29 int r = x + dir[0]; 30 int c = y + dir[1]; 31 if (r >= 0 && r < m && c >= 0 && c < n && grid[r][c] != 'X' && !visited[r][c]) { 32 visited[r][c] = true; 33 queue.offer(new int[] { r, c }); 34 } 35 } 36 } 37 step++; 38 } 39 return -1; 40 } 41 }
二刷我再提供一個不需要 visited 數組的代碼。這里我直接把訪問過的坐標標記為 X,就不會再次被處理了。
1 class Solution { 2 int m; 3 int n; 4 5 public int getFood(char[][] grid) { 6 int res = Integer.MAX_VALUE; 7 m = grid.length; 8 n = grid[0].length; 9 Queue<int[]> queue = new LinkedList<>(); 10 for (int i = 0; i < m; i++) { 11 for (int j = 0; j < n; j++) { 12 if (grid[i][j] == '*') { 13 queue.offer(new int[] { i, j, 0 }); 14 } 15 } 16 } 17 18 int[] dx = {-1, 1, 0, 0}; 19 int[] dy = {0, 0, -1, 1}; 20 while (!queue.isEmpty()) { 21 int[] cur = queue.poll(); 22 int x = cur[0]; 23 int y = cur[1]; 24 int step = cur[2]; 25 for (int k = 0; k < 4; k++) { 26 int newX = x + dx[k]; 27 int newY = y + dy[k]; 28 if (newX >= 0 && newX < m && newY >= 0 && newY < n) { 29 if (grid[newX][newY] == '#') { 30 return step + 1; 31 } else if (grid[newX][newY] == 'O') { 32 grid[newX][newY] = 'X'; 33 queue.offer(new int[] { newX, newY, step + 1 }); 34 } 35 } 36 } 37 } 38 return -1; 39 } 40 }
相關題目
