@@ -108,32 +108,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3568.Mi
108108
109109<!-- solution:start -->
110110
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}$ 是垃圾单元格的数量。
112122
113123<!-- tabs:start -->
114124
115125#### Python3
116126
117127``` 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
119172```
120173
121174#### Java
122175
123176``` 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+ }
125235```
126236
127237#### C++
128238
129239``` 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+ };
131299```
132300
133301#### Go
134302
135303```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+ }
137380```
138381
139382<!-- tabs: end -->
0 commit comments