Leetcode 3568. Minimum Moves to Clean the Classroom
- 题目链接:3568. Minimum Moves to Clean the Classroom
1. 解题思路
这一题我的核心思路就是广度优先遍历遍历+剪枝。
显然,我们可以给出一个广度优先遍历来给出所有可能的走法直至无法继续或者捡完所有垃圾。
但是,上述情况事实上可能会无限循环下去,而且所有的走法也非常浪费,因此,我们需要对其进行剪枝,从而优化我们的计算。
而这里,我的剪枝思路就是:
- 如果一个点曾经走过,则当他重新回到这个点的时候,他必须满足以下两个条件之一,否则这条路线必然不会是最优的,可以直接忽略:
- 他在中间的过程中捡过了新的垃圾;
- 他在中间的过程中补充了能量(即回来时的能量值大于之前来的时候的能量值)
由此,我们就能对上述问题进行解答了。
2. 代码实现
给出python代码实现如下:
class Solution: def minMoves(self, classroom: List[str], energy: int) -> int: n, m = len(classroom), len(classroom[0]) k, mapping, seen = 0, {}, {} for i in range(n): for j in range(m): if classroom[i][j] == \"L\": mapping[(i, j)] = k k += 1 elif classroom[i][j] == \"S\": start = (0, 0, -energy, i, j) seen[(0, i, j)] = energy if k == 0: return 0 q = [start] while q: step, status, e, i, j = heapq.heappop(q) status = -status e = -e if status == (2**k)-1: return step elif e <= 0: continue if i-1 >= 0 and classroom[i-1][j] != \"X\": new_status = status if classroom[i-1][j] != \"L\" else status | (1 << mapping[(i-1, j)]) new_energy = e-1 if classroom[i-1][j] != \"R\" else energy if seen.get((new_status, i-1, j), -1) < new_energy: heapq.heappush(q, (step+1, -new_status, -new_energy, i-1, j)) seen[(new_status, i-1, j)] = new_energy if i+1 < n and classroom[i+1][j] != \"X\": new_status = status if classroom[i+1][j] != \"L\" else status | (1 << mapping[(i+1, j)]) new_energy = e-1 if classroom[i+1][j] != \"R\" else energy if seen.get((new_status, i+1, j), -1) < new_energy: heapq.heappush(q, (step+1, -new_status, -new_energy, i+1, j)) seen[(new_status, i+1, j)] = new_energy if j-1 >= 0 and classroom[i][j-1] != \"X\": new_status = status if classroom[i][j-1] != \"L\" else status | (1 << mapping[(i, j-1)]) new_energy = e-1 if classroom[i][j-1] != \"R\" else energy if seen.get((new_status, i, j-1), -1) < new_energy: heapq.heappush(q, (step+1, -new_status, -new_energy, i, j-1)) seen[(new_status, i, j-1)] = new_energy if j+1 < m and classroom[i][j+1] != \"X\": new_status = status if classroom[i][j+1] != \"L\" else status | (1 << mapping[(i, j+1)]) new_energy = e-1 if classroom[i][j+1] != \"R\" else energy if seen.get((new_status, i, j+1), -1) < new_energy: heapq.heappush(q, (step+1, -new_status, -new_energy, i, j+1)) seen[(new_status, i, j+1)] = new_energy return -1
提交代码评测得到:耗时3097ms,占用内存58.28MB。