OJ练习第99题——推箱子

news2024/9/27 23:25:01

推箱子

力扣链接:1263. 推箱子

题目描述

「推箱子」是一款风靡全球的益智小游戏,玩家需要将箱子推到仓库中的目标位置。

游戏地图用大小为 m x n 的网格 grid 表示,其中每个元素可以是墙、地板或者是箱子。

现在你将作为玩家参与游戏,按规则将箱子 ‘B’ 移动到目标位置 ‘T’ :

玩家用字符 ‘S’ 表示,只要他在地板上,就可以在网格中向上、下、左、右四个方向移动。
地板用字符 ‘.’ 表示,意味着可以自由行走。
墙用字符 ‘#’ 表示,意味着障碍物,不能通行。
箱子仅有一个,用字符 ‘B’ 表示。相应地,网格上有一个目标位置 ‘T’。
玩家需要站在箱子旁边,然后沿着箱子的方向进行移动,此时箱子会被移动到相邻的地板单元格。记作一次「推动」。
玩家无法越过箱子。
返回将箱子推到目标位置的最小 推动 次数,如果无法做到,请返回 -1。

示例

在这里插入图片描述
输入:grid = [[“#”,“#”,“#”,“#”,“#”,“#”],
[“#”,“T”,“#”,“#”,“#”,“#”],
[“#”,“.”,“.”,“B”,“.”,“#”],
[“#”,“.”,“#”,“#”,“.”,“#”],
[“#”,“.”,“.”,“.”,“S”,“#”],
[“#”,“#”,“#”,“#”,“#”,“#”]]
输出:3
解释:我们只需要返回推箱子的次数。

Java代码

class Solution {
    //箱子视角进行BFS,人视角进行DFS,后者作为前者得以行进的前提
    public int minPushBox(char[][] grid) {
        int m = grid.length, n = grid[0].length;

        //遍历一次,找出箱子起点/终点,人的位置
        int startX = -1, startY = -1;
        int targetX = -1, targetY = -1;
        int personX = -1, personY = -1;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(grid[i][j] == 'B') {
                    startX = i;
                    startY = j;
                }
                if(grid[i][j] == 'T') {
                    targetX = i;
                    targetY = j;
                    grid[i][j] = '.';
                }
                if(grid[i][j] == 'S') {
                    personX = i;
                    personY = j;
                    grid[i][j] = '.';
                }
            }
        }

        //初始化队列,加入元素以启动BFS
        boolean[][][] visited = new boolean[m][n][4];
        Queue<Box> queue = new LinkedList<>();
        for(int i = 0; i < 4; i++) {
            int[] direction = directions[i];
            if(personCanReach(grid, m, n, personX, personY, startX - direction[0], startY - direction[1], new boolean[m][n])) {
                queue.add(new Box(startX, startY, i));
                visited[startX][startY][i] = true;
            }
        }

        //以箱子的视角开始BFS
        int step = 0;
        while(!queue.isEmpty()) {
            int size = queue.size();
            while(size-- > 0) {
                Box box = queue.poll();
                grid[box.x][box.y] = 'B';
                personX = box.x - directions[box.from][0];
                personY = box.y - directions[box.from][1];
                if(box.x == targetX && box.y == targetY) {
                    return step;
                }
                for(int i=0; i < 4; i++) {
                    int[] direction = directions[i];
                    int nextX = box.x + direction[0];
                    int nextY = box.y + direction[1];
                    //人能否绕到箱子后面?
                    if(!personCanReach(grid, m, n, personX, personY, box.x - direction[0], box.y - direction[1], new boolean[m][n])) {
                        continue;
                    }

                    //箱子的下个位置是否合法?
                    if(!isValid(grid, m, n, nextX, nextY)) {
                        continue;
                    }

                    //箱子的下一个状态是否重复?
                    if(visited[nextX][nextY][i]) {
                        continue;
                    }
                    queue.add(new Box(nextX, nextY, i));
                    visited[nextX][nextY][i] = true;
                }
                grid[box.x][box.y] = '.';
            }
            step++;
        }
        return -1;
    }
    //其含义是上/下/左/右变换的动作
    private final static int[][] directions = {{-1,0}, {1,0}, {0,-1}, {0,1}};

    //静态内部类是个顶级类,可以当成外部类来看
    private static class Box{
        int x, y;
        int from;
        public Box(int x, int y, int from) {
            this.x = x;
            this.y = y;
            this.from = from;
        }
    }

    //人是否可以从某一位置(startX, startY)到达另一位置(targetX, targetY)
    private boolean personCanReach(char[][] grid, int m, int n, int startX, int startY, int targetX, int targetY, boolean[][] visited) {
        if(startX == targetX && startY == targetY) {
            return true;
        }
        visited[startX][startY] = true;
        for(int[] direction : directions) {
            int nextX = startX + direction[0];
            int nextY = startY + direction[1];
            if(isValid(grid, m, n, nextX, nextY) && !visited[nextX][nextY]) {
                if(personCanReach(grid, m, n, nextX, nextY, targetX, targetY, visited)) {
                    return true;
                }
            }
        }
        return false;
    }
    //某位置是否可以踏足
    private boolean isValid(char[][] grid, int m, int n, int x, int y) {
        return x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '.';
    }
}

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-moves-to-move-a-box-to-their-target-location
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/504433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习—神经网络基础原理

前向传播&#xff08;Forward&#xff09; 为什么要有激活函数 这里用两层来代表多层的神经网络举例&#xff1a;第一层的输出是第二层的输入&#xff0c;其中MM的W*X矩阵乘法&#xff0c;ADD是向量加法即加上偏置&#xff0c;如果每一层都只有线性变换&#xff0c;那么最终无…

Modbus转Profibus网关连接安科瑞ARD3T电机保护器接到300PLC配置案例

案例介绍兴达易控Modbus转profibus网关&#xff08;XD-MDPB100&#xff09;把安科瑞ARD3T电机保护器在博图软件里无需编程实现由profibus转modbus协议之间的互转&#xff0c;用到的设备安科瑞ARD3T电机保护器一台&#xff1b;兴达易控Modbus转profibus网关&#xff08;XD-MDPN1…

解密Diem币:探索Facebook的数字货币计划

大家好&#xff01;我是ClonBrowser小鱼&#xff0c;今天我要和大家一起解密一种备受关注的数字货币——Diem币。 或许你已经猜到了&#xff0c;这个数字货币与社交媒体巨头Facebook有关。是的没错&#xff0c;Facebook正计划推出一种自己的加密货币&#xff0c;名为Diem币。让…

为什么做白平衡?康耐视Visionpro和Basler pylon,海康MVS如何做白平衡-三种软件相同条件下,白平衡效果一样?

为什么会有白平衡这个问题? 因为不同颜色的差异来自于不同波长光线的比例不同。 由于在不同色温下各种波长光纤比例的不同,造成白色在高色温的光线照射下显得较蓝,在低色温度的光线下显得较黄。如下图: 问题:在相同条件下,康耐视Visionpro和Basler pylon,海康MVS做白平…

机器学习决策树、回归树 sklearn-day1

#文章很多内容来自菜菜老师的课件。仅做笔记一、决策树 1、模块 2、sklearn基本建模流程 #分类树对应的代码 from sklearn import tree #导入需要的模块 clf tree.DecisionTreeClassifier() #实例化 clf clf.fit(X_train,y_train) #用训练集数据训练模型 result clf…

JavaWeb 中 Filter过滤器

Filter过滤器 每博一文案 师傅说&#xff1a;人生无坦途&#xff0c;累是必须的背负&#xff0c;看多了&#xff0c;人情人暖&#xff0c;走遍了离合聚散&#xff0c;有时会 在心里对自己说&#xff0c;我想&#xff0c;我是真的累了&#xff0c;小时候有读不完的书&#xff0…

大学生志愿者管理信息系统设计与实现(论文+源码)_kaic

摘 要 在国家的十四五期间&#xff0c;志愿服务成为推动社会文明发展的重要力量。大学生是志愿活动的中坚力量。现有的志愿管理工作不能满足志愿活动的需要&#xff0c;存在活动找不到志愿者&#xff0c;志愿者找不到活动的情况。为服务良好的志愿服务体系&#xff0c;对大学…

Hologres技术揭秘: JSON半结构化数据的极致分析性能

作者&#xff1a;王华峰&#xff08;花名继儒&#xff09;&#xff0c;Hologres研发 近年来&#xff0c;随着移动端应用的普及&#xff0c;应用埋点、用户标签计算等场景开始诞生&#xff0c;为了更好的支撑这类场景&#xff0c;越来越多的大数据系统开始使用半结构化JSON格式…

保姆级教程:OpenAI获取Account详细教程2023/05/09最新

前言 最近OpenAI封的比较严重&#xff0c;建议大家不要批量&#xff0c;容易被封&#xff0c;也不要用公用的IP 一、上网 首先你要学会上网&#xff08;懂&#xff1f;&#xff09;、这一步是必须的。 现在MG等地方的IP已经很难了&#xff0c;可以选择一些小众国家的IP 二、开…

【论文阅读】Online multi-sensor calibration based on moving object tracking

目录 Online multi-sensor calibration based on moving object trackingAbstract1. Introduction2. Proposed Method2.1 Object Detection2.2 Tracking of moving objects2.3 Track-to-track association2.4 Decalibration(解关联) detection2.5 Graph-based extrinsic calibr…

花菁染料CY5.5标记活性脂 Cy5.5-NHS

Cy5.5 NHS ester用于染色蛋白质、标记DNA、标记细胞表面抗原、标记抗体和其他生物分子。Cy5.5 NHS ester还可以用于分子影像学&#xff0c;可以追踪细胞内的变化。它还可以用于荧光免疫检测&#xff0c;以检测细胞表面抗原和抗体。 产品名称&#xff1a;五甲川花菁染料CY5.5标记…

OpenGL 4.0的Tessellation Shader(细分曲面着色器)

细分曲面着色器&#xff08;Tessellation Shader&#xff09;处于顶点着色器阶段的下一个阶段&#xff0c;我们可以看以下链接的OpenGL渲染流水线的图&#xff1a;Rendering Pipeline Overview。它是由ATI在2001年率先设计出来的。 目录 细分曲面着色器细分曲面Patch细分曲面控…

手把手实现项目中自定义动态数据源?

手把手实现项目中自定义动态数据源&#xff1f; 第一步&#xff1a;创建项目&#xff0c;添加POM依赖第二步&#xff1a;添加application.yml配置文件第三步&#xff1a;自定义注解指定使用哪个数据源第四步&#xff1a;创建DynamicDataSourceContextHolder工具类&#xff0c;存…

LeetCode:347. 前 K 个高频元素

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340; 算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 题解目录 一、&#x1f331;[347. 前 K 个高频元素](https://leetcode.cn/problems/bina…

安全防线再升级 | 中睿天下全流量安全分析系统重磅回归

随着信息化的加速&#xff0c;企业网络日趋完善。企业数字化的加速&#xff0c;让越来越多的关键业务运行在计算机网络基础之上&#xff0c;越来越多的重要信息通过网络传送&#xff0c;企业网络面临日益严重的安全威胁&#xff0c;这些安全威胁以窃取信息和收集情报为主&#…

基于docker安装MySQL

为了更好的管理&#xff0c;打算把MySQL、redis等服务放在虚拟机中统一部署&#xff0c;这样不会因为这些服务的问题影响到系统本身。前段时间正好在看docker相关的内容&#xff0c;打算在虚拟机中通过docker来使用MySQL等服务。 这次先记录安装MySQL的过程。 docker安装 首先…

超越 Nginx!号称下一代 Web 服务器,用起来够优雅!

Nginx是一款非常流行的Web服务器&#xff0c;在Github上已有16KStar&#xff0c;我们经常用它来做静态资源托管或反向代理。最近发现了一款全新的Web服务器Caddy&#xff0c;Star数超越Nginx&#xff0c;标星38KStar。试用了一下Caddy&#xff0c;发现它使用起来比Nginx优雅多了…

掌握这五个核心步骤,让你的方案完美无缺

写策划方案怎么来写&#xff0c;可能会是刚入行策划人的难点&#xff0c;策划方案其实就是一份营销计划&#xff0c;一份完整的策划能让策划人看清自己、认清竞争对手&#xff0c;形成对市场的整体认知。 一般大的营销策划方案里面会用到STP、SWOT和4P等模型&#xff0c;模型本…

【Java多线程编程】创建线程的基本方式

大家好&#xff0c;我是一只爱打拳的程序猿。今天给大家带来的内容是 Java 创建线程的基本方式。 多线程的基本创建方式: 继承Thread类实现Runnable接口匿名内部类使用lambda表达式 目录 1. 继承Thread类 1.1 Thread类启动线程 2. 实现Runnable接口 2.1 创建Thread类实例…

while和until的使用方法(还有一些小实验:计算器、猜价格游戏、购物)

while和until的使用方法 一、while用法二、Until循环语句三、猜价格小实验四、计算器实验六、购物实验 一、while用法 for循环语句非常适用于列表对象无规律&#xff0c;且列表来源以固定&#xff08;如某个列表文件&#xff09;的场合。而对于要求控制循环次数&#xff0c;操…