|
53 | 53 |
|
54 | 54 | <!-- 这里可写通用的实现逻辑 -->
|
55 | 55 |
|
| 56 | +**方法一:双端队列 BFS(0-1 BFS)** |
| 57 | + |
| 58 | +每走到一个格子 $(i, j)$,有 $4$ 个方向可以走,如果方向与当前格子的方向相同,那么不需要施法,否则需要施法一次。 |
| 59 | + |
| 60 | +因此,我们可以使用 BFS 求出从起点到终点的最短路径。 |
| 61 | + |
| 62 | +我们定义一个双端队列 $q$,存储当前可以到达的格子,每次从队首取出一个格子 $(i, j)$,然后向四个方向扩展,如果扩展的格子 $(x, y)$ 不需要施法,那么将其加入队首,否则加入队尾。当我们第一次到达终点时,就得到了最短路径。 |
| 63 | + |
| 64 | +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。 |
| 65 | + |
56 | 66 | <!-- tabs:start -->
|
57 | 67 |
|
58 | 68 | ### **Python3**
|
59 | 69 |
|
60 | 70 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
61 | 71 |
|
62 | 72 | ```python
|
63 |
| - |
| 73 | +class Solution: |
| 74 | + def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int: |
| 75 | + dirs = (-1, 0, 1, 0, -1) |
| 76 | + d = {"^": 0, "v": 2, "<": 3, ">": 1} |
| 77 | + i, j = start |
| 78 | + q = deque([(i, j)]) |
| 79 | + m, n = len(matrix), len(matrix[0]) |
| 80 | + dist = [[inf] * n for _ in range(m)] |
| 81 | + dist[i][j] = 0 |
| 82 | + while 1: |
| 83 | + i, j = q.popleft() |
| 84 | + if i == end[0] and j == end[1]: |
| 85 | + return int(dist[i][j]) |
| 86 | + for k in range(4): |
| 87 | + x, y = i + dirs[k], j + dirs[k + 1] |
| 88 | + t = dist[i][j] + int(k != d[matrix[i][j]]) |
| 89 | + if 0 <= x < m and 0 <= y < n and t < dist[x][y]: |
| 90 | + dist[x][y] = t |
| 91 | + if dist[x][y] == dist[i][j]: |
| 92 | + q.appendleft((x, y)) |
| 93 | + else: |
| 94 | + q.append((x, y)) |
64 | 95 | ```
|
65 | 96 |
|
66 | 97 | ### **Java**
|
67 | 98 |
|
68 | 99 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
69 | 100 |
|
70 | 101 | ```java
|
| 102 | +class Solution { |
| 103 | + public int conveyorBelt(String[] matrix, int[] start, int[] end) { |
| 104 | + int[] dirs = {-1, 0, 1, 0, -1}; |
| 105 | + Map<Character, Integer> d = new HashMap<>(4); |
| 106 | + d.put('^', 0); |
| 107 | + d.put('>', 1); |
| 108 | + d.put('v', 2); |
| 109 | + d.put('<', 3); |
| 110 | + Deque<int[]> q = new ArrayDeque<>(); |
| 111 | + q.offer(new int[] {start[0], start[1]}); |
| 112 | + int m = matrix.length, n = matrix[0].length(); |
| 113 | + int[][] dist = new int[m][n]; |
| 114 | + for (int[] row : dist) { |
| 115 | + Arrays.fill(row, 1 << 30); |
| 116 | + } |
| 117 | + dist[start[0]][start[1]] = 0; |
| 118 | + while (true) { |
| 119 | + int[] p = q.poll(); |
| 120 | + int i = p[0], j = p[1]; |
| 121 | + if (i == end[0] && j == end[1]) { |
| 122 | + return dist[i][j]; |
| 123 | + } |
| 124 | + for (int k = 0; k < 4; ++k) { |
| 125 | + int x = i + dirs[k], y = j + dirs[k + 1]; |
| 126 | + int t = dist[i][j] + (k == d.get(matrix[i].charAt(j)) ? 0 : 1); |
| 127 | + if (x >= 0 && x < m && y >= 0 && y < n && t < dist[x][y]) { |
| 128 | + dist[x][y] = t; |
| 129 | + if (dist[x][y] == dist[i][j]) { |
| 130 | + q.offerFirst(new int[] {x, y}); |
| 131 | + } else { |
| 132 | + q.offerLast(new int[] {x, y}); |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | + } |
| 137 | + } |
| 138 | +} |
| 139 | +``` |
| 140 | + |
| 141 | +### **C++** |
| 142 | + |
| 143 | +```cpp |
| 144 | +class Solution { |
| 145 | +public: |
| 146 | + int conveyorBelt(vector<string>& matrix, vector<int>& start, vector<int>& end) { |
| 147 | + int dirs[5] = {-1, 0, 1, 0, -1}; |
| 148 | + unordered_map<char, int> d; |
| 149 | + d['^'] = 0; |
| 150 | + d['>'] = 1; |
| 151 | + d['v'] = 2; |
| 152 | + d['<'] = 3; |
| 153 | + deque<pair<int, int>> q; |
| 154 | + q.emplace_back(start[0], start[1]); |
| 155 | + int m = matrix.size(), n = matrix[0].size(); |
| 156 | + int dist[m][n]; |
| 157 | + memset(dist, 0x3f, sizeof(dist)); |
| 158 | + dist[start[0]][start[1]] = 0; |
| 159 | + while (1) { |
| 160 | + auto [i, j] = q.front(); |
| 161 | + q.pop_front(); |
| 162 | + if (i == end[0] && j == end[1]) { |
| 163 | + return dist[i][j]; |
| 164 | + } |
| 165 | + for (int k = 0; k < 4; ++k) { |
| 166 | + int x = i + dirs[k], y = j + dirs[k + 1]; |
| 167 | + int t = dist[i][j] + (k == d[matrix[i][j]] ? 0 : 1); |
| 168 | + if (x >= 0 && x < m && y >= 0 && y < n && t < dist[x][y]) { |
| 169 | + dist[x][y] = t; |
| 170 | + if (dist[x][y] == dist[i][j]) { |
| 171 | + q.emplace_front(x, y); |
| 172 | + } else { |
| 173 | + q.emplace_back(x, y); |
| 174 | + } |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + } |
| 179 | +}; |
| 180 | +``` |
| 181 | +
|
| 182 | +### **Go** |
| 183 | +
|
| 184 | +```go |
| 185 | +func conveyorBelt(matrix []string, start []int, end []int) int { |
| 186 | + dirs := [5]int{-1, 0, 1, 0, -1} |
| 187 | + d := map[byte]int{ |
| 188 | + '^': 0, |
| 189 | + '>': 1, |
| 190 | + 'v': 2, |
| 191 | + '<': 3, |
| 192 | + } |
| 193 | + q := [][2]int{[2]int{start[0], start[1]}} |
| 194 | + m, n := len(matrix), len(matrix[0]) |
| 195 | + dist := make([][]int, m) |
| 196 | + for i := range dist { |
| 197 | + dist[i] = make([]int, n) |
| 198 | + for j := range dist[i] { |
| 199 | + dist[i][j] = 1 << 30 |
| 200 | + } |
| 201 | + } |
| 202 | + dist[start[0]][start[1]] = 0 |
| 203 | + for { |
| 204 | + p := q[0] |
| 205 | + i, j := p[0], p[1] |
| 206 | + if i == end[0] && j == end[1] { |
| 207 | + return dist[i][j] |
| 208 | + } |
| 209 | + q = q[1:] |
| 210 | + for k := 0; k < 4; k++ { |
| 211 | + x, y := i+dirs[k], j+dirs[k+1] |
| 212 | + t := dist[i][j] |
| 213 | + if k != d[matrix[i][j]] { |
| 214 | + t++ |
| 215 | + } |
| 216 | + if x >= 0 && x < m && y >= 0 && y < n && t < dist[x][y] { |
| 217 | + dist[x][y] = t |
| 218 | + if dist[x][y] == dist[i][j] { |
| 219 | + q = append([][2]int{[2]int{x, y}}, q...) |
| 220 | + } else { |
| 221 | + q = append(q, [2]int{x, y}) |
| 222 | + } |
| 223 | + } |
| 224 | + } |
| 225 | + } |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +### **TypeScript** |
71 | 230 |
|
| 231 | +```ts |
| 232 | +function conveyorBelt( |
| 233 | + matrix: string[], |
| 234 | + start: number[], |
| 235 | + end: number[], |
| 236 | +): number { |
| 237 | + const dirs = [-1, 0, 1, 0, -1]; |
| 238 | + const d: Map<string, number> = new Map(); |
| 239 | + d.set('^', 0); |
| 240 | + d.set('>', 1); |
| 241 | + d.set('v', 2); |
| 242 | + d.set('<', 3); |
| 243 | + const q: number[][] = [start]; |
| 244 | + const m = matrix.length; |
| 245 | + const n = matrix[0].length; |
| 246 | + const dist: number[][] = Array(m) |
| 247 | + .fill(0) |
| 248 | + .map(() => Array(n).fill(1 << 30)); |
| 249 | + dist[start[0]][start[1]] = 0; |
| 250 | + while (true) { |
| 251 | + const [i, j] = q.shift()!; |
| 252 | + if (i === end[0] && j === end[1]) { |
| 253 | + return dist[i][j]; |
| 254 | + } |
| 255 | + for (let k = 0; k < 4; ++k) { |
| 256 | + const x = i + dirs[k]; |
| 257 | + const y = j + dirs[k + 1]; |
| 258 | + const t = dist[i][j] + (d.get(matrix[i][j]) === k ? 0 : 1); |
| 259 | + if (x >= 0 && x < m && y >= 0 && y < n && t < dist[x][y]) { |
| 260 | + dist[x][y] = t; |
| 261 | + if (t == dist[i][j]) { |
| 262 | + q.unshift([x, y]); |
| 263 | + } else { |
| 264 | + q.push([x, y]); |
| 265 | + } |
| 266 | + } |
| 267 | + } |
| 268 | + } |
| 269 | +} |
72 | 270 | ```
|
73 | 271 |
|
74 | 272 | ### **...**
|
|
0 commit comments