Skip to content

Commit ae56113

Browse files
committed
feat: add solutions to lc problem: No.3568
No.3568.Minimum Moves to Clean the Classroom
1 parent 90f55e9 commit ae56113

File tree

6 files changed

+733
-10
lines changed

6 files changed

+733
-10
lines changed

solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README.md

Lines changed: 248 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)