LeeCode LCP.13 寻宝【python】

这么高频的题,这么难是我万万没想到的,差点当场裂开,这里就写一写博主研究官方答案和一众博主的思路,然后研究了很久得到的思路以及代码,就差抄了!!!!淦。
有一说一,这道题快把我写哭了,一个转行的菜鸡太难了,呜呜呜。

建议大家还是耐下心来看看,思路和注释很详细,看完这个篇文章再搞不懂这个题,我直接裂开。
在这里插入图片描述

【题目】

我们得到了一副藏宝图,藏宝图显示,在一个迷宫中存在着未被世人发现的宝藏。

迷宫是一个二维矩阵,用一个字符串数组表示。它标识了唯一的入口(用 ‘S’ 表示),和唯一的宝藏地点(用 ‘T’ 表示)。但是,宝藏被一些隐蔽的机关保护了起来。在地图上有若干个机关点(用 ‘M’ 表示),只有所有机关均被触发,才可以拿到宝藏。

要保持机关的触发,需要把一个重石放在上面。迷宫中有若干个石堆(用 ‘O’ 表示),每个石堆都有无限个足够触发机关的重石。但是由于石头太重,我们一次只能搬一个石头到指定地点。

迷宫中同样有一些墙壁(用 ‘#’ 表示),我们不能走入墙壁。剩余的都是可随意通行的点(用 ‘.’ 表示)。石堆、机关、起点和终点(无论是否能拿到宝藏)也是可以通行的。

我们每步可以选择向上/向下/向左/向右移动一格,并且不能移出迷宫。搬起石头和放下石头不算步数。那么,从起点开始,我们最少需要多少步才能最后拿到宝藏呢?如果无法拿到宝藏,返回 -1 。

示例 1:

输入: [“S#O”, “M…”, “M.T”]

输出:16

解释:最优路线为: S->O, cost = 4, 去搬石头 O->第二行的M, cost = 3, M机关触发 第二行的M->O, cost = 3, 我们需要继续回去 O 搬石头。 O->第三行的M, cost = 4, 此时所有机关均触发 第三行的M->T, cost = 2,去T点拿宝藏。 总步数为16。

示例 2:

输入: [“S#O”, “M.#”, “M.T”]

输出:-1

解释:我们无法搬到石头触发机关

示例 3:

输入: [“S#O”, “M.T”, “M…”]

输出:17

解释:注意终点也是可以通行的。

限制:

1 <= maze.length <= 100
1 <= maze[i].length <= 100
maze[i].length == maze[j].length
S 和 T 有且只有一个
0 <= M的数量 <= 16
0 <= O的数量 <= 40,题目保证当迷宫中存在 M 时,一定存在至少一个 O 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xun-bao
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【解题思路】

这里卡了太久,一直在整理思路,所采用的是BFS和动态规划,最后整理到的结果大概如下。
1、预处理
这道题归根结底是S(起点)–>O(石堆)–>M(机关)–>…–>O–>M–>T(终点)的过程,而且其中的O、M均不唯一,即可以将其分为三个距离::S–>O, M–>O(因为逆向返回路径相同),M–>T
这就需要我们计算出:
1)任意起点到所有点的距离start-to-pos,进而得出起点到石堆位置
2)计算出某机关到各处的位置,M–>anypos,进而得出M–>O和M–>T
3)由1、2计算出任意起点经过石堆O到机关的位置,start-to-O-to-M,这一步需要进行遍历
4)并同时计算出M-to-O-to-M,并存入列表中
预处理采用的最主要的算法就是BFS。
2、动态规划
在预处理中我们已经计算出S-O-M、M-O-M,此时只需要采用动态规划,计算出min(S-to-T)。

【python代码】

class Solution:
    def minimalSteps(self, maze: List[str]) -> int:
        #首先进行预处理
        m = len(maze)
        n = len(maze[0])
        start_x, start_y, t_x, t_y = -1,-1,-1,-1

        #设置数组储存M和O,数组元素为元组坐标
        M = []
        stone = []
        for i in range(len(maze)):
            for j in range(len(maze[i])):
                if maze[i][j] == 'M':
                    M.append((i, j))
                if maze[i][j] == 'O':
                    stone.append
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值