|
| 1 | +# [1293. Shortest Path in a Grid with Obstacles Elimination](https://leetcode.com/problems/shortest-path-in-a-grid-with-obstacles-elimination/) |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +## 题目 |
| 6 | + |
| 7 | +You are given an m x n integer matrix grid where each cell is either 0 (empty) or 1 (obstacle). You can move up, down, left, or right from and to an empty cell in one step. |
| 8 | + |
| 9 | +Return the minimum number of steps to walk from the upper left corner (0, 0) to the lower right corner (m - 1, n - 1) given that you can eliminate at most k obstacles. If it is not possible to find such walk return -1. |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +Example 1: |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | +``` |
| 20 | +Input: grid = [[0,0,0],[1,1,0],[0,0,0],[0,1,1],[0,0,0]], k = 1 |
| 21 | +Output: 6 |
| 22 | +Explanation: |
| 23 | +The shortest path without eliminating any obstacle is 10. |
| 24 | +The shortest path with one obstacle elimination at position (3,2) is 6. Such path is (0,0) -> (0,1) -> (0,2) -> (1,2) -> (2,2) -> (3,2) -> (4,2). |
| 25 | +``` |
| 26 | + |
| 27 | +Example 2: |
| 28 | + |
| 29 | + |
| 30 | + |
| 31 | +``` |
| 32 | +Input: grid = [[0,1,1],[1,1,1],[1,0,0]], k = 1 |
| 33 | +Output: -1 |
| 34 | +Explanation: We need to eliminate at least two obstacles to find such a walk. |
| 35 | +``` |
| 36 | + |
| 37 | +Constraints: |
| 38 | + |
| 39 | +- m == grid.length |
| 40 | +- n == grid[i].length |
| 41 | +- 1 <= m, n <= 40 |
| 42 | +- 1 <= k <= m * n |
| 43 | +- grid[i][j] is either 0 or 1. |
| 44 | +- grid[0][0] == grid[m - 1][n - 1] == 0 |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +## 题目大意 |
| 49 | + |
| 50 | +给你一个 m * n 的网格,其中每个单元格不是 0(空)就是 1(障碍物)。每一步,您都可以在空白单元格中上、下、左、右移动。 |
| 51 | + |
| 52 | +如果您 最多 可以消除 k 个障碍物,请找出从左上角 (0, 0) 到右下角 (m-1, n-1) 的最短路径,并返回通过该路径所需的步数。如果找不到这样的路径,则返回 -1 。 |
| 53 | + |
| 54 | + |
| 55 | +## 解题思路 |
| 56 | + |
| 57 | +使用 BFS 遍历棋盘。这题比普通可达性问题多了一个障碍物的限制。这个也不难。每个点往周边四个方向扩展的时候,如果遇到障碍物,先算上这个障碍物,障碍物累积总个数小于 K 的时候,从障碍物的这个格子继续开始遍历。如果没有遇到障碍物,判断当前累积障碍物个数是否已经小于 K 个,如果小于 K 便继续遍历。如果大于 K,便终止此轮遍历。 |
| 58 | + |
| 59 | +## 代码 |
| 60 | + |
| 61 | +```go |
| 62 | +var dir = [][]int{ |
| 63 | + {-1, 0}, |
| 64 | + {0, 1}, |
| 65 | + {1, 0}, |
| 66 | + {0, -1}, |
| 67 | +} |
| 68 | + |
| 69 | +type pos struct { |
| 70 | + x, y int |
| 71 | + obstacle int |
| 72 | + step int |
| 73 | +} |
| 74 | + |
| 75 | +func shortestPath(grid [][]int, k int) int { |
| 76 | + queue, m, n := []pos{}, len(grid), len(grid[0]) |
| 77 | + visitor := make([][][]int, m) |
| 78 | + if len(grid) == 1 && len(grid[0]) == 1 { |
| 79 | + return 0 |
| 80 | + } |
| 81 | + for i := 0; i < m; i++ { |
| 82 | + visitor[i] = make([][]int, n) |
| 83 | + for j := 0; j < n; j++ { |
| 84 | + visitor[i][j] = make([]int, k+1) |
| 85 | + } |
| 86 | + } |
| 87 | + visitor[0][0][0] = 1 |
| 88 | + queue = append(queue, pos{x: 0, y: 0, obstacle: 0, step: 0}) |
| 89 | + for len(queue) > 0 { |
| 90 | + size := len(queue) |
| 91 | + for size > 0 { |
| 92 | + size-- |
| 93 | + node := queue[0] |
| 94 | + queue = queue[1:] |
| 95 | + for i := 0; i < len(dir); i++ { |
| 96 | + newX := node.x + dir[i][0] |
| 97 | + newY := node.y + dir[i][1] |
| 98 | + if newX == m-1 && newY == n-1 { |
| 99 | + if node.obstacle != 0 { |
| 100 | + if node.obstacle <= k { |
| 101 | + return node.step + 1 |
| 102 | + } else { |
| 103 | + continue |
| 104 | + } |
| 105 | + } |
| 106 | + return node.step + 1 |
| 107 | + } |
| 108 | + if isInBoard(grid, newX, newY) { |
| 109 | + if grid[newX][newY] == 1 { |
| 110 | + if node.obstacle+1 <= k && visitor[newX][newY][node.obstacle+1] != 1 { |
| 111 | + queue = append(queue, pos{x: newX, y: newY, obstacle: node.obstacle + 1, step: node.step + 1}) |
| 112 | + visitor[newX][newY][node.obstacle+1] = 1 |
| 113 | + } |
| 114 | + } else { |
| 115 | + if node.obstacle <= k && visitor[newX][newY][node.obstacle] != 1 { |
| 116 | + queue = append(queue, pos{x: newX, y: newY, obstacle: node.obstacle, step: node.step + 1}) |
| 117 | + visitor[newX][newY][node.obstacle] = 1 |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + } |
| 122 | + } |
| 123 | + } |
| 124 | + } |
| 125 | + return -1 |
| 126 | +} |
| 127 | + |
| 128 | +func isInBoard(board [][]int, x, y int) bool { |
| 129 | + return x >= 0 && x < len(board) && y >= 0 && y < len(board[0]) |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | + |
| 134 | +---------------------------------------------- |
| 135 | +<div style="display: flex;justify-content: space-between;align-items: center;"> |
| 136 | +<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1200~1299/1290.Convert-Binary-Number-in-a-Linked-List-to-Integer/">⬅️上一页</a></p> |
| 137 | +<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1200~1299/1295.Find-Numbers-with-Even-Number-of-Digits/">下一页➡️</a></p> |
| 138 | +</div> |
0 commit comments