@@ -108,32 +108,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3568.Mi
108
108
109
109
<!-- solution:start -->
110
110
111
- ### 方法一
111
+ ### 方法一:BFS
112
+
113
+ 我们可以使用广度优先搜索(BFS)来解决这个问题。首先,我们需要找到学生的起始位置,并记录所有垃圾的位置。然后,我们可以使用 BFS 来探索从起始位置出发的所有可能路径,同时跟踪当前能量和已收集的垃圾。
114
+
115
+ 在 BFS 中,我们需要维护一个状态,包括当前的位置、剩余的能量和已收集的垃圾掩码。我们可以使用一个队列来存储这些状态,并使用一个集合来记录已经访问过的状态,以避免重复访问。
116
+
117
+ 我们从起始位置开始,尝试向四个方向移动。如果移动到一个垃圾单元格,我们将更新已收集的垃圾掩码。如果移动到一个重置区域,我们将能量恢复到最大值。每次移动都会消耗 1 单位能量。
118
+
119
+ 如果我们在 BFS 中找到了一个状态,其中已收集的垃圾掩码为 0(表示所有垃圾都已收集),则返回当前的移动次数。如果 BFS 完成后仍未找到这样的状态,则返回 -1。
120
+
121
+ 时间复杂度 $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$,空间复杂度 $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$,其中 $m$ 和 $n$ 分别是网格的行数和列数,而 $\textit{count}$ 是垃圾单元格的数量。
112
122
113
123
<!-- tabs:start -->
114
124
115
125
#### Python3
116
126
117
127
``` python
118
-
128
+ class Solution :
129
+ def minMoves (self , classroom : List[str ], energy : int ) -> int :
130
+ m, n = len (classroom), len (classroom[0 ])
131
+ d = [[0 ] * n for _ in range (m)]
132
+ x = y = cnt = 0
133
+ for i, row in enumerate (classroom):
134
+ for j, c in enumerate (row):
135
+ if c == " S" :
136
+ x, y = i, j
137
+ elif c == " L" :
138
+ d[i][j] = cnt
139
+ cnt += 1
140
+ if cnt == 0 :
141
+ return 0
142
+ vis = [
143
+ [[[False ] * (1 << cnt) for _ in range (energy + 1 )] for _ in range (n)]
144
+ for _ in range (m)
145
+ ]
146
+ q = [(x, y, energy, (1 << cnt) - 1 )]
147
+ vis[x][y][energy][(1 << cnt) - 1 ] = True
148
+ dirs = (- 1 , 0 , 1 , 0 , - 1 )
149
+ ans = 0
150
+ while q:
151
+ t = q
152
+ q = []
153
+ for i, j, cur_energy, mask in t:
154
+ if mask == 0 :
155
+ return ans
156
+ if cur_energy <= 0 :
157
+ continue
158
+ for k in range (4 ):
159
+ x, y = i + dirs[k], j + dirs[k + 1 ]
160
+ if 0 <= x < m and 0 <= y < n and classroom[x][y] != " X" :
161
+ nxt_energy = (
162
+ energy if classroom[x][y] == " R" else cur_energy - 1
163
+ )
164
+ nxt_mask = mask
165
+ if classroom[x][y] == " L" :
166
+ nxt_mask &= ~ (1 << d[x][y])
167
+ if not vis[x][y][nxt_energy][nxt_mask]:
168
+ vis[x][y][nxt_energy][nxt_mask] = True
169
+ q.append((x, y, nxt_energy, nxt_mask))
170
+ ans += 1
171
+ return - 1
119
172
```
120
173
121
174
#### Java
122
175
123
176
``` java
124
-
177
+ class Solution {
178
+ public int minMoves (String [] classroom , int energy ) {
179
+ int m = classroom. length, n = classroom[0 ]. length();
180
+ int [][] d = new int [m][n];
181
+ int x = 0 , y = 0 , cnt = 0 ;
182
+ for (int i = 0 ; i < m; i++ ) {
183
+ String row = classroom[i];
184
+ for (int j = 0 ; j < n; j++ ) {
185
+ char c = row. charAt(j);
186
+ if (c == ' S' ) {
187
+ x = i;
188
+ y = j;
189
+ } else if (c == ' L' ) {
190
+ d[i][j] = cnt;
191
+ cnt++ ;
192
+ }
193
+ }
194
+ }
195
+ if (cnt == 0 ) {
196
+ return 0 ;
197
+ }
198
+ boolean [][][][] vis = new boolean [m][n][energy + 1 ][1 << cnt];
199
+ List<int[]> q = new ArrayList<> ();
200
+ q. add(new int [] {x, y, energy, (1 << cnt) - 1 });
201
+ vis[x][y][energy][(1 << cnt) - 1 ] = true ;
202
+ int [] dirs = {- 1 , 0 , 1 , 0 , - 1 };
203
+ int ans = 0 ;
204
+ while (! q. isEmpty()) {
205
+ List<int[]> t = q;
206
+ q = new ArrayList<> ();
207
+ for (int [] state : t) {
208
+ int i = state[0 ], j = state[1 ], curEnergy = state[2 ], mask = state[3 ];
209
+ if (mask == 0 ) {
210
+ return ans;
211
+ }
212
+ if (curEnergy <= 0 ) {
213
+ continue ;
214
+ }
215
+ for (int k = 0 ; k < 4 ; k++ ) {
216
+ int nx = i + dirs[k], ny = j + dirs[k + 1 ];
217
+ if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx]. charAt(ny) != ' X' ) {
218
+ int nxtEnergy = classroom[nx]. charAt(ny) == ' R' ? energy : curEnergy - 1 ;
219
+ int nxtMask = mask;
220
+ if (classroom[nx]. charAt(ny) == ' L' ) {
221
+ nxtMask &= ~ (1 << d[nx][ny]);
222
+ }
223
+ if (! vis[nx][ny][nxtEnergy][nxtMask]) {
224
+ vis[nx][ny][nxtEnergy][nxtMask] = true ;
225
+ q. add(new int [] {nx, ny, nxtEnergy, nxtMask});
226
+ }
227
+ }
228
+ }
229
+ }
230
+ ans++ ;
231
+ }
232
+ return - 1 ;
233
+ }
234
+ }
125
235
```
126
236
127
237
#### C++
128
238
129
239
``` cpp
130
-
240
+ class Solution {
241
+ public:
242
+ int minMoves(vector<string >& classroom, int energy) {
243
+ int m = classroom.size(), n = classroom[ 0] .size();
244
+ vector<vector<int >> d(m, vector<int >(n, 0));
245
+ int x = 0, y = 0, cnt = 0;
246
+ for (int i = 0; i < m; ++i) {
247
+ string& row = classroom[ i] ;
248
+ for (int j = 0; j < n; ++j) {
249
+ char c = row[ j] ;
250
+ if (c == 'S') {
251
+ x = i;
252
+ y = j;
253
+ } else if (c == 'L') {
254
+ d[ i] [ j ] = cnt;
255
+ cnt++;
256
+ }
257
+ }
258
+ }
259
+ if (cnt == 0) {
260
+ return 0;
261
+ }
262
+ vector<vector<vector<vector<bool >>>> vis(m, vector<vector<vector<bool >>>(n, vector<vector<bool >>(energy + 1, vector<bool >(1 << cnt, false))));
263
+ queue<tuple<int, int, int, int>> q;
264
+ q.emplace(x, y, energy, (1 << cnt) - 1);
265
+ vis[ x] [ y ] [ energy] [ (1 << cnt) - 1 ] = true;
266
+ vector<int > dirs = {-1, 0, 1, 0, -1};
267
+ int ans = 0;
268
+ while (!q.empty()) {
269
+ int sz = q.size();
270
+ while (sz--) {
271
+ auto [ i, j, cur_energy, mask] = q.front();
272
+ q.pop();
273
+ if (mask == 0) {
274
+ return ans;
275
+ }
276
+ if (cur_energy <= 0) {
277
+ continue;
278
+ }
279
+ for (int k = 0; k < 4; ++k) {
280
+ int nx = i + dirs[ k] , ny = j + dirs[ k + 1] ;
281
+ if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[ nx] [ ny ] != 'X') {
282
+ int nxt_energy = classroom[ nx] [ ny ] == 'R' ? energy : cur_energy - 1;
283
+ int nxt_mask = mask;
284
+ if (classroom[ nx] [ ny ] == 'L') {
285
+ nxt_mask &= ~ (1 << d[ nx] [ ny ] );
286
+ }
287
+ if (!vis[ nx] [ ny ] [ nxt_energy] [ nxt_mask ] ) {
288
+ vis[ nx] [ ny ] [ nxt_energy] [ nxt_mask ] = true;
289
+ q.emplace(nx, ny, nxt_energy, nxt_mask);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ ans++;
295
+ }
296
+ return -1;
297
+ }
298
+ };
131
299
```
132
300
133
301
#### Go
134
302
135
303
```go
136
-
304
+ func minMoves(classroom []string, energy int) int {
305
+ m, n := len(classroom), len(classroom[0])
306
+ d := make([][]int, m)
307
+ for i := range d {
308
+ d[i] = make([]int, n)
309
+ }
310
+ x, y, cnt := 0, 0, 0
311
+ for i := 0; i < m; i++ {
312
+ row := classroom[i]
313
+ for j := 0; j < n; j++ {
314
+ c := row[j]
315
+ if c == 'S' {
316
+ x, y = i, j
317
+ } else if c == 'L' {
318
+ d[i][j] = cnt
319
+ cnt++
320
+ }
321
+ }
322
+ }
323
+ if cnt == 0 {
324
+ return 0
325
+ }
326
+
327
+ vis := make([][][][]bool, m)
328
+ for i := range vis {
329
+ vis[i] = make([][][]bool, n)
330
+ for j := range vis[i] {
331
+ vis[i][j] = make([][]bool, energy+1)
332
+ for e := range vis[i][j] {
333
+ vis[i][j][e] = make([]bool, 1<<cnt)
334
+ }
335
+ }
336
+ }
337
+ type state struct {
338
+ i, j, curEnergy, mask int
339
+ }
340
+ q := []state{{x, y, energy, (1 << cnt) - 1}}
341
+ vis[x][y][energy][(1<<cnt)-1] = true
342
+ dirs := []int{-1, 0, 1, 0, -1}
343
+ ans := 0
344
+
345
+ for len(q) > 0 {
346
+ t := q
347
+ q = []state{}
348
+ for _, s := range t {
349
+ i, j, curEnergy, mask := s.i, s.j, s.curEnergy, s.mask
350
+ if mask == 0 {
351
+ return ans
352
+ }
353
+ if curEnergy <= 0 {
354
+ continue
355
+ }
356
+ for k := 0; k < 4; k++ {
357
+ nx, ny := i+dirs[k], j+dirs[k+1]
358
+ if nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X' {
359
+ var nxtEnergy int
360
+ if classroom[nx][ny] == 'R' {
361
+ nxtEnergy = energy
362
+ } else {
363
+ nxtEnergy = curEnergy - 1
364
+ }
365
+ nxtMask := mask
366
+ if classroom[nx][ny] == 'L' {
367
+ nxtMask &= ^(1 << d[nx][ny])
368
+ }
369
+ if !vis[nx][ny][nxtEnergy][nxtMask] {
370
+ vis[nx][ny][nxtEnergy][nxtMask] = true
371
+ q = append(q, state{nx, ny, nxtEnergy, nxtMask})
372
+ }
373
+ }
374
+ }
375
+ }
376
+ ans++
377
+ }
378
+ return -1
379
+ }
137
380
```
138
381
139
382
<!-- tabs: end -->
0 commit comments