Leetcode 3568. Minimum Moves to Clean the Classroom

  • [Leetcode 3568. Minimum Moves to Clean the Classroom](#Leetcode 3568. Minimum Moves to Clean the Classroom)
    • [1. 解题思路](#1. 解题思路)
    • [2. 代码实现](#2. 代码实现)

1. 解题思路

这一题我的核心思路就是广度优先遍历遍历+剪枝。

显然,我们可以给出一个广度优先遍历来给出所有可能的走法直至无法继续或者捡完所有垃圾。

但是,上述情况事实上可能会无限循环下去,而且所有的走法也非常浪费,因此,我们需要对其进行剪枝,从而优化我们的计算。

而这里,我的剪枝思路就是:

  • 如果一个点曾经走过,则当他重新回到这个点的时候,他必须满足以下两个条件之一,否则这条路线必然不会是最优的,可以直接忽略:
    • 他在中间的过程中捡过了新的垃圾;
    • 他在中间的过程中补充了能量(即回来时的能量值大于之前来的时候的能量值)

由此,我们就能对上述问题进行解答了。

2. 代码实现

给出python代码实现如下:

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。

相关推荐
CoderYanger9 小时前
递归、搜索与回溯-穷举vs暴搜vs深搜vs回溯vs剪枝:12.全排列
java·算法·leetcode·机器学习·深度优先·剪枝·1024程序员节
前端小L19 小时前
回溯算法专题(五):去重与剪枝的双重奏——攻克「组合总和 II」
算法·剪枝
CoderYanger2 天前
递归、搜索与回溯-穷举vs暴搜vs深搜vs回溯vs剪枝:13.子集
java·算法·leetcode·机器学习·剪枝·1024程序员节
黑客思维者2 天前
底层冗余性原理探秘模型剪枝(Pruning)为何能“无损”压缩模型?
算法·机器学习·剪枝
_OP_CHEN8 天前
算法基础篇:(十六)深度优先搜索(DFS)之递归型枚举与回溯剪枝初识
算法·深度优先·剪枝
b***748811 天前
2025年前端开发新方向预测
剪枝·activemq·argocd
1白天的黑夜114 天前
递归-二叉树中的剪枝-814.二叉树剪枝-力扣(LeetCode)
c++·leetcode·剪枝·递归
未若君雅裁14 天前
LeetCode 51 - N皇后问题 详解笔记
java·数据结构·笔记·算法·leetcode·剪枝
大千AI助手15 天前
代价复杂度剪枝(CCP)详解:原理、实现与应用
人工智能·决策树·机器学习·剪枝·大千ai助手·代价复杂度剪枝·ccp
玖剹16 天前
穷举 VS 暴搜 VS 深搜 VS 回溯 VS 剪枝
c语言·c++·算法·深度优先·剪枝·深度优先遍历