1210. 穿过迷宫的最少移动次数

news2025/1/16 18:43:42

你还记得那条风靡全球的贪吃蛇吗?

我们在一个 n*n 的网格上构建了新的迷宫地图,蛇的长度为 2,也就是说它会占去两个单元格。蛇会从左上角((0, 0) 和 (0, 1))开始移动。我们用 0 表示空单元格,用 1 表示障碍物。蛇需要移动到迷宫的右下角((n-1, n-2) 和 (n-1, n-1))。

每次移动,蛇可以这样走:

  • 如果没有障碍,则向右移动一个单元格。并仍然保持身体的水平/竖直状态。
  • 如果没有障碍,则向下移动一个单元格。并仍然保持身体的水平/竖直状态。
  • 如果它处于水平状态并且其下面的两个单元都是空的,就顺时针旋转 90 度。蛇从((r, c)(r, c+1))移动到 ((r, c)(r+1, c))。

  • 如果它处于竖直状态并且其右面的两个单元都是空的,就逆时针旋转 90 度。蛇从((r, c)(r+1, c))移动到((r, c)(r, c+1))。

返回蛇抵达目的地所需的最少移动次数。

如果无法到达目的地,请返回 -1

示例 1:

输入:grid = [[0,0,0,0,0,1],
               [1,1,0,0,1,0],
               [0,0,0,0,1,1],
               [0,0,1,0,1,0],
               [0,1,1,0,0,0],
               [0,1,1,0,0,0]]
输出:11
解释:
一种可能的解决方案是 [右, 右, 顺时针旋转, 右, 下, 下, 下, 下, 逆时针旋转, 右, 下]。

示例 2:

输入:grid = [[0,0,1,1,1,1],
               [0,0,0,0,1,1],
               [1,1,0,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,1],
               [1,1,1,0,0,0]]
输出:9

提示:

  • 2 <= n <= 100
  • 0 <= grid[i][j] <= 1
  • 蛇保证从空单元格开始出发。

类似于走迷宫,运动人物从占一个格变成占两个格,运动方向从上下左右变成左右旋转,使用广度优先遍历解决此类问题,在同一个位置有三种方式行动,每次行动又会有新的位置生成,生成新的位置就会有新的运动路径(即三种方式)。使用队列将每次的三种方式都走一遍后将新的位置结点放入队列,并记录当前运动次数。直到循环结束,返回结果。

class Solution {
    public int minimumMoves(int[][] grid) {
        int n = grid.length;
        //记录每个结点的运动次数
        int[][][] dist = new int[n][n][2];
        for (int i = 0;i < n;i++){
            for (int j = 0;j < n;j++){
                //初始化数组
                Arrays.fill(dist[i][j],-1);
            }
        }
        ArrayDeque<int[]> queue = new ArrayDeque<>();
        dist[0][0][0] = 0;
        //队列中放入位置和当前横竖状态
        queue.offer(new int[]{0,0,0});
        while (!queue.isEmpty()){
            int[] arr = queue.poll();
            //位置参数
            int x = arr[0],y = arr[1],status = arr[2];
            //根据当前状态以及是否有空格位置判断下一步走向
            if (status == 0) {
                // 向右移动一个单元格
                if (y + 2 < n && dist[x][y + 1][0] == -1 && grid[x][y + 2] == 0) {
                    //运动次数++
                    dist[x][y + 1][0] = dist[x][y][0] + 1;
                    //将下一步的可执行路径放入到队列中
                    queue.offer(new int[]{x, y + 1, 0});
                }
                // 向下移动一个单元格
                if (x + 1 < n && dist[x + 1][y][0] == -1 && grid[x + 1][y] == 0 && grid[x + 1][y + 1] == 0) {
                    dist[x + 1][y][0] = dist[x][y][0] + 1;
                    queue.offer(new int[]{x + 1, y, 0});
                }
                // 顺时针旋转 90 度
                if (x + 1 < n && y + 1 < n && dist[x][y][1] == -1 && grid[x + 1][y] == 0 && grid[x + 1][y + 1] == 0) {
                    dist[x][y][1] = dist[x][y][0] + 1;
                    queue.offer(new int[]{x, y, 1});
                }
            } else {
                // 向右移动一个单元格
                if (y + 1 < n && dist[x][y + 1][1] == -1 && grid[x][y + 1] == 0 && grid[x + 1][y + 1] == 0) {
                    dist[x][y + 1][1] = dist[x][y][1] + 1;
                    queue.offer(new int[]{x, y + 1, 1});
                }
                // 向下移动一个单元格
                if (x + 2 < n && dist[x + 1][y][1] == -1 && grid[x + 2][y] == 0) {
                    dist[x + 1][y][1] = dist[x][y][1] + 1;
                    queue.offer(new int[]{x + 1, y, 1});
                }
                // 逆时针旋转 90 度
                if (x + 1 < n && y + 1 < n && dist[x][y][0] == -1 && grid[x][y + 1] == 0 && grid[x + 1][y + 1] == 0) {
                    dist[x][y][0] = dist[x][y][1] + 1;
                    queue.offer(new int[]{x, y, 0});
                }
            }
        }
        //返回移动次数,如果没有到达则会返回一个数组的初始化值-1
        return dist[n-1][n-2][0];
    }
}

 动态规划

力扣

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

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

相关文章

题目 3166: 蓝桥杯2023年第十四届省赛真题-阶乘的和--不能完全通过,最好情况通过67.

原题链接&#xff1a; 题目 3166: 蓝桥杯2023年第十四届省赛真题-阶乘的和 https://www.dotcpp.com/oj/problem3166.html 致歉 害&#xff0c;首先深感抱歉&#xff0c;这道题还是没有找到很好的解决办法。目前最好情况就是67分。 这道题先这样跳过吧&#xff0c;当然以后还…

RabbitMQ 03 直连模式-可视化界面

这里先演示最简单的模型&#xff1a;直连模式。其结构图为&#xff1a; 一个生产者 -> 消息队列 -> 一个消费者 生产者只需要将数据丢进消息队列&#xff0c;而消费者只需要将数据从消息队列中取出&#xff0c;这样就实现了生产者和消费者的消息交互。 创建一个新的实验…

CLion开发工具 | 05 - 使用CLion开发ESP32

专栏介绍 一、准备工作 电脑上安装好ESP-IDF环境本文参考Jetbrains官方视频教程&#xff1a;在 Windows 上用 CLion 开发 ESP32 | CLion教程 | 嵌入式开发 | IDE 二、打开工程 复制一份新的helloworld工程。 使用CLion打开该工程。 选择信任该工程。 CLion打开后自动打开…

Linux 基础语法 -2

如果我们以后再Linux当中 写了一些命名&#xff0c;导致程序我们不能进行操作了&#xff0c;如这个死循环&#xff1a; 他就会一直输出 "hello Linux" &#xff0c;我们就使用 ctrl c 来终止因为程序或者指令异常&#xff0c;而导致我们无法进行指令输入&#xff…

2023/04/27~28 刷题记录

D - JoJos Incredible Adventures 大致题义&#xff1a; 有一串由 0,1 构成的字符串&#xff0c;每次循环右移一位&#xff0c;行编号从 0 一直到 n-1。求这些行里由 1 构成的最大矩形面积。 题解&#xff1a; 我们其实可以观察到一串连续的 1 经过右移后是会形成一对正三角和…

C# WebService的开发以及客户端调用

目录 1、WebService简介 1.1 什么是XML&#xff1f; 1.2 什么是Soap&#xff1f; 1.3 什么是WSDL&#xff1f; 2、WebService与WebApi的区别与优缺点 2.1 WebService与WebApi的区别&#xff1a; 2.2 WebService的优缺点&#xff1a; 2.3 WebApi的优缺点&#xff1a; 3…

ShardingJDBC 数据库分片 流式处理+归并排序 优化原理刨析

1. 分库分表下的分页查询 业务数据达到一定数据量时&#xff0c;必定会引入数据库分片&#xff0c;但当对于分片的情况下&#xff0c;分页查询是如何做到的&#xff1f; 比如: 数据库db1&#xff0c;中有三个user表&#xff0c;user_0&#xff0c;user_1&#xff0c;user_2&a…

FreeRTOS 信号量(五) ------ 递归互斥信号量

文章目录 一、递归互斥信号量简介二、创建互斥信号量1. xSemaphoreCreateRecursiveMutex()2. xSemaphoreCreateRecursiveMutexStatic() 三、递归信号量创建过程分析四、释放递归互斥信号量五、获取递归互斥信号量六、递归互斥信号量使用示例 一、递归互斥信号量简介 递归互斥信…

Linux学习[8]文件权限深入2 默认权限umask SUID/SGID/SBIT file指令

文章目录 前言1. 默认权限umask1.1 默认权限含义1.2 查看默认权限1.3 默认权限在文件与目录的异同 2. 特殊权限2.1 SUID2.2 SGID2.3 SBIT2.4 SUID/SGID/SBIT 权限设置2.4.1 数字法2.4.2 符号法 3. file指令 前言 在linux学习6里面&#xff0c;通过ls -al命令列出文件的所有详细…

2023/4/30周报

目录 摘要 论文阅读 1、题目和现存问题 2、知识空间理论、GRU和自注意力机制 3、模型构建 4、实验准备 5、实验结果 深度学习 1、GRU 2、代码实例 3、GRU和GCN结合的可能性 总结 摘要 本周在论文阅读上&#xff0c;阅读了一篇基于自注意力机制和双向GRU神经网络的…

【MATLAB数据处理实用案例详解(17)】——利用概念神经网络实现柴油机故障诊断

目录 一、问题描述二、利用概念神经网络实现柴油机故障诊断原理三、算法步骤3.1 定义样本3.2 样本归一化3.3 创建网络模型3.4 测试3.5 显示结果 四、运行结果五、完整代码 一、问题描述 柴油机的结构较为复杂&#xff0c;工作状况非常恶劣&#xff0c;因此发生故障的可能性较大…

linux常用命令大全

作为开发者&#xff0c;Linux是我们必须掌握的操作系统之一。因此&#xff0c;在编写代码和部署应用程序时&#xff0c;熟练使用Linux命令非常重要。这些常用命令不得不会&#xff0c;掌握这些命令&#xff0c;工作上会事半功倍&#xff0c;大大提高工作效率。 一. 文件和目录…

python使用迭代法验证角谷猜想

def fun(n):print(n)while n ! 1:n 3 * n 1 if n % 2 else n / 2print(finished)for i in range(2,1000):fun(i) 1、了解了什么是"角谷猜想" 对于任意一个自然数n,若n为偶数,则将其除以2;若n为奇数,则将其乘以3,然后再加1。如此经过有限次运算后,总可以得到自然数…

【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2

【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2 0、前言Abstract1 Introduction2 Background2.1 Vector Quantized Variational AutoEncoder 3 Method3.1 Stage 1: Learning Hierarchical Latent Codes3.2 Stage 2: Learning Priors over Latent …

【STM32】知识补充 晶振的基本原理及其应用

【STM32】知识补充 晶振的基本原理及其应用 概述晶振的基本原理晶振的性能参数晶振的分类晶振的应用晶振器在 STM32 上的应用总结 概述 晶振作为现代电子技中的重要组件, 广泛应用于各种电子设备中, 起到稳定时钟信号的作用. 本文将为您解释晶振的基本原理及其在实际应用中的用…

第 02 章 OSPF实验

2.1 OSPF 回顾 2.1.1 实验目的 在 CCNA 中&#xff0c;我们学习到了 OSPF 是一个链路状态路由协议&#xff0c;和 RIP 以及 EIGRP 的最大 不同在于对于它们对于网络的认识以及根本的算法的不同。通过对 CCNA 中 OSPF 配置实验 的回顾&#xff0c;从中加强我们对 OSPF 的理解。…

带你学c带你飞-P7取值范围

比特位 CPU能读懂的最小单元——比特位&#xff0c;bit&#xff0c;b 字节 内存机构的最小寻址单元——字节&#xff0c;Byte&#xff0c;B 1Byte8bit 进制 怎么算 注意&#xff1a;int默认是signed类型&#xff0c;signed类型第一位是符号位 符号位 存放signed类型的存…

对比体验 ChatGPT,聊聊文心一言的优缺点

在昨天文心一言发布后&#xff0c;我第一时间拿到了体验的资格&#xff0c;但第一次使用后却不禁有些失望。他的逻辑能力极度缺乏、创造力也差点意思。不过&#xff0c;今天再次高强度使用后&#xff0c;却又让我对这款产品的想法有了些许改变。 前言 将 2023 年称为 AI 纪元…

西门子PLC沿脉冲类指令汇总

S7-1200CPU提供了四种沿脉冲指令供用户使用&#xff0c;分别为&#xff1a;扫描操作数信号边沿指令、在信号边沿置位操作数的指令、扫描RLO的信号边沿指令以及检测信号边沿指令。 信号从0--1的时刻称为上升沿&#xff0c;信号从1--0的时刻称为下降沿&#xff0c;不管是上升沿还…

【VM服务管家】VM4.0平台SDK_2.1环境配置类

目录 2.1.1 环境配置&#xff1a;CSharp二次开发环境配置方法2.1.2 环境配置&#xff1a;Qt二次开发环境配置方法2.1.3 环境配置&#xff1a;MFC二次开发环境配置方法2.1.4 环境配置&#xff1a;VB.Net二次开发环境配置方法2.1.5 环境配置&#xff1a;运行出现Vm.Core.Solution…