蛇梯棋[中等]

一、题目

给你一个大小为n x n的整数矩阵board,方格按从1n2编号,编号遵循 转行交替方式 ,从左下角开始 (即,从board[n - 1][0]开始)每一行交替方向。玩家从棋盘上的方格1(总是在最后一行、第一列)开始出发。每一回合,玩家需要从当前方格curr开始出发,按下述要求前进:
1、选定目标方格next,目标方格的编号符合范围[curr + 1, min(curr + 6, n2)]。该选择模拟了掷 六面体骰子 的情景,无论棋盘大小如何,玩家最多只能有6个目的地。
2、传送玩家:如果目标方格next处存在蛇或梯子,那么玩家会传送到蛇或梯子的目的地。否则,玩家传送到目标方格next。当玩家到达编号n2的方格时,游戏结束。

rc列的棋盘,按前述方法编号,棋盘格中可能存在 “蛇” 或 “梯子”;如果board[r][c] != -1,那个蛇或梯子的目的地将会是board[r][c]。编号为1n2的方格上没有蛇或梯子。

注意,玩家在每回合的前进过程中最多只能爬过蛇或梯子一次:就算目的地是另一条蛇或梯子的起点,玩家也 不能 继续移动。

举个例子,假设棋盘是[[-1,4],[-1,3]],第一次移动,玩家的目标方格是2。那么这个玩家将会顺着梯子到达方格3,但 不能 顺着方格3上的梯子前往方格4

返回达到编号为n2的方格所需的最少移动次数,如果不可能,则返回-1

示例 1:

输入:board = [[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,35,-1,-1,13,-1],[-1,-1,-1,-1,-1,-1],[-1,15,-1,-1,-1,-1]]
输出:4
解释:
首先,从方格1[第5行,第0列] 开始。
先决定移动到方格2,并必须爬过梯子移动到到方格15
然后决定移动到方格17[第3行,第4列],必须爬过蛇到方格13
接着决定移动到方格14,且必须通过梯子移动到方格35
最后决定移动到方格36, 游戏结束。
可以证明需要至少4次移动才能到达最后一个方格,所以答案是4

示例 2:

输入:board = [[-1,-1],[-1,3]]
输出:1

n == board.length == board[i].length
2 <= n <= 20
grid[i][j]的值是-1或在范围[1, n2]
编号为1n2的方格上没有蛇或梯子

二、代码

广度优先搜索: 我们可以将棋盘抽象成一个包含N^2个节点的有向图,对于每个节点x,若x+i (1≤i≤6)上没有蛇或梯子,则连一条从xx+i的有向边;否则记蛇梯的目的地为y,连一条从xy的有向边。如此转换后,原问题等价于在这张有向图上求出从1N^2的最短路长度。

对于该问题,我们可以使用广度优先搜索。将节点编号和到达该节点的移动次数作为搜索状态,顺着该节点的出边扩展新状态,直至到达终点N^2,返回此时的移动次数。若无法到达终点则返回−1

代码实现时,我们可以用一个队列来存储搜索状态,初始时将起点状态(1,0)加入队列,表示当前位于起点1,移动次数为0。然后不断取出队首,每次取出队首元素时扩展新状态,即遍历该节点的出边,若出边对应节点未被访问,则将该节点和移动次数加一的结果作为新状态,加入队列。如此循环直至到达终点或队列为空。

此外,我们需要计算出编号在棋盘中的对应行列,以便从board中得到目的地。设编号为id,由于每行有n个数字,其位于棋盘从下往上数的第⌊(id−1)/n⌋行,记作r。由于棋盘的每一行会交替方向,若r为偶数,则编号方向从左向右,列号为(id−1) mod n;若r为奇数,则编号方向从右向左,列号为n−1−((id−1) mod n)

class Solution {
    public int snakesAndLadders(int[][] board) {
        int n = board.length;
        boolean[] vis = new boolean[n * n + 1];
        Queue<int[]> queue = new LinkedList<int[]>();
        queue.offer(new int[]{1, 0});
        while (!queue.isEmpty()) {
            int[] p = queue.poll();
            for (int i = 1; i <= 6; ++i) {
                int nxt = p[0] + i;
                if (nxt > n * n) { // 超出边界
                    break;
                }
                int[] rc = id2rc(nxt, n); // 得到下一步的行列
                if (board[rc[0]][rc[1]] > 0) { // 存在蛇或梯子
                    nxt = board[rc[0]][rc[1]];
                }
                if (nxt == n * n) { // 到达终点
                    return p[1] + 1;
                }
                if (!vis[nxt]) {
                    vis[nxt] = true;
                    queue.offer(new int[]{nxt, p[1] + 1}); // 扩展新状态
                }
            }
        }
        return -1;
    }

    public int[] id2rc(int id, int n) {
        int r = (id - 1) / n, c = (id - 1) % n;
        if (r % 2 == 1) {
            c = n - 1 - c;
        }
        return new int[]{n - 1 - r, c};
    }
}

时间复杂度: O(N^2),其中N为棋盘board的边长。棋盘的每个格子至多入队一次,因此时间复杂度为O(N^2)
空间复杂度: O(N2)。我们需要O(N^2)的空间来存储每个格子是否被访问过。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

礼品企业网站搭建的作用是什么

礼品一般分为企业定制礼品和零售现成礼品&#xff0c;二者都有很强的市场需求度。同时对礼品企业而言&#xff0c;一般主要以批发为主&#xff0c;客户也主要是零售商或企业。 1、拓客难 不同于零售&#xff0c;即使没有引流&#xff0c;入驻商场或街边小摊也总会有自然客户。…

【C++篇】Vector容器 Vector嵌套容器

文章目录 &#x1f354;简述vector&#x1f384;vector存放内置数据类型⭐创建一个vector容器⭐向容器里面插入数据⭐通过迭代器访问容器里面的数据⭐遍历&#x1f388;第一种遍历方式&#x1f388;第二种遍历方式&#x1f388;第三种遍历方式 &#x1f384;vector存放自定义数…

揭秘 Go 中 Goroutines 轻量级并发

理解 Goroutines、它们的效率以及同步挑战 并发是现代软件开发的一个基本概念&#xff0c;使程序能够同时执行多个任务。在 Go 编程领域&#xff0c;理解 Goroutines 是至关重要的。本文将全面概述 Goroutines&#xff0c;它们的轻量级特性&#xff0c;如何使用 go 关键字创建…

FPGA模块——以太网(1)MDIO读写

FPGA模块——以太网MDIO读写 MDIO接口介绍MDIO接口代码&#xff08;1&#xff09;MDIO接口驱动代码&#xff08;2&#xff09;使用MDIO驱动的代码 MDIO接口介绍 MDIO是串行管理接口。MAC 和 PHY 芯片有一个配置接口&#xff0c;即 MDIO 接口&#xff0c;可以配置 PHY 芯片的工…

Ubuntu 常用命令之 ifconfig 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 ifconfig 是一个用于配置和显示 Linux 内核中网络接口的系统管理命令。它用于配置&#xff0c;管理和查询 TCP/IP 网络接口参数。 ifconfig 命令的参数有很多&#xff0c;以下是一些常见的参数 up&#xff1a;激活指定的网络接口…

Java学习系列(五)

1.继承 继承是java面向对象编程技术的一块基石&#xff0c;因为它允许创建分等级层次的类。 继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父类相…

实现单链表的基本操作(力扣、牛客刷题的基础笔试题常客)

本节来学习单链表的实现。在链表的刷题中&#xff0c;单链表占主导地位&#xff0c;很多oj题都在在单链表的背景下进行&#xff1b;而且很多链表的面试题都是以单链表为背景命题。所以&#xff0c;学好单链表的基本操作很重要 目录 一.介绍单链表 1.链表及单链表 2.定义一个…

生活中的物理2——人类迷惑行为(用笔扎手)

1实验 材料 笔、手 实验 1、先用手轻轻碰一下笔尖&#xff08;未成年人须家长监护&#xff09; 2、再用另一只手碰碰笔尾 你发现了什么&#xff1f;&#xff1f; 2发现 你会发现碰笔尖的手明显比碰笔尾的手更痛 你想想为什么 3原理 压强f/s 笔尖的面积明显比笔尾的小 …

C#文件操作(二)

一、前言 文章的续作前文是&#xff1a; C#文件操作&#xff08;一&#xff09;-CSDN博客https://blog.csdn.net/qq_71897293/article/details/135117922?spm1001.2014.3001.5501 二、流 流是序列化设备的抽象表示序列化设备可以线性方式储存数据并可按照同样的方式访问一次…

【QT】QGraphicsView和QGraphicsItem坐标转换

坐标转换 QGraphicsItem和QGraphicsView之间的坐标转换需要通过QGraphicsScene进行转换 QGraphicsView::mapToScene() - 视图 -> 场景QGraphicsView::mapFromScene() - 场景 -> 视图QGraphicsItem::mapToScene() - 图元 -> 场景QGraphicsItem::mapFromScene() - 场景 …

Java异常类分类,所有子类的父类是什么

1.异常的层次机构&#xff1a; 所有异常的父类是Throwable&#xff0c;它有两个子类&#xff0c;分别是Error和Exception。 2.Error&#xff1a; 表示系统错误&#xff0c;通常不能处理和恢复。比如StackOverFlowError或者OutOfMemoryError&#xff0c;出了问题只能结束程序…

【项目问题解决】% sql注入问题

目录 【项目问题解决】% sql注入问题 1.问题描述2.问题原因3.解决思路4.解决方案1.前端限制传入特殊字符2.后端拦截特殊字符-正则表达式3.后端拦截特殊字符-拦截器 5.总结6.参考 文章所属专区 项目问题解决 1.问题描述 在处理接口入参的一些sql注入问题&#xff0c;虽然通过M…

【matlab】绘制竖状双组渐变柱状图

【matlab】绘制竖状双组渐变柱状图

【krita】实时绘画 入门到精通 海报+电商+装修+人物

安装插件 首先打开comfyUI&#xff0c;再打开krita&#xff0c;出现问题提示&#xff0c; 打开 cd custom_nodes 输入命令 安装控件 git clone https://github.com/Acly/comfyui-tooling-nodes.git krita基础设置 设置模型 设置lora &#xff08;可设置lora强度 增加更多…

使用yarn安装electron时手动选择版本

访问1Password或者其他可以提供随机字符的网站&#xff0c;获取随机密码运行安装命令 操作要点&#xff0c;必须触发Couldnt find any versions for "electron" that matches "*"才算成功 将复制的随机密码粘贴到后面 例如&#xff1a;yarn add --dev elec…

智能优化算法应用:基于堆优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于堆优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于堆优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.堆优化算法4.实验参数设定5.算法结果6.参考文…

Python自动化测试系列[v1.0.0][常见页面操作处理]

[智能等待] # 用于实现智能等待页面元素的出现 # encoding utf-8 """ __title__ __author__ davieyang __mtime__ 2018/4/21 """ from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait …

制作系统盘

老毛桃&#xff08;LaoMaoTao&#xff09; 制作启动盘 第一步.进入官方网站下载我们的老毛桃 下载老毛桃U盘制作工具后&#xff0c;双击打开老毛桃的运行程序。 打开老毛桃U盘制作工具&#xff0c;插入需要制作的U盘&#xff08;如图所示U盘winpe系统制作界面&#xff09;。…

ansible在ubuntu下的安装和使用

ansible在ubuntu下的安装和使用 本文目录 ansible在ubuntu下的安装和使用安装和配置虚拟机配置安装和验证 简单使用创建 ansible cfg 和 inventory 文件创建剧本并执行使用 ansible vault 加密 安装和配置 中文文档&#xff1a;http://www.ansible.com.cn/docs/intro_installa…

玩具乐器企业网站建设的作用是什么

玩具乐器的市场需求度非常高&#xff0c;对玩具乐器厂家而言&#xff0c;经销批量卖货是主要的&#xff0c;然而却并不容易&#xff0c;玩具乐器厂商品牌宣传及拓客转化方面面临痛点&#xff1a; 1、线上无平台、拓客难 玩具乐器商家缺少品牌宣传方式&#xff0c;线下难以拓展…