leetcode909:蛇梯棋

给你一个大小为 n x n 的整数矩阵 board ,方格按从 1n2 编号,编号遵循 转行交替方式从左下角开始 (即,从 board[n - 1][0] 开始)的每一行改变方向。

你一开始位于棋盘上的方格 1。每一回合,玩家需要从当前方格 curr 开始出发,按下述要求前进:

  • 选定目标方格 next ,目标方格的编号在范围 [curr + 1, min(curr + 6, n2)]
    • 该选择模拟了掷 六面体骰子 的情景,无论棋盘大小如何,玩家最多只能有 6 个目的地。
  • 传送玩家:如果目标方格 next 处存在蛇或梯子,那么玩家会传送到蛇或梯子的目的地。否则,玩家传送到目标方格 next
  • 当玩家到达编号 n2 的方格时,游戏结束。

如果 board[r][c] != -1 ,位于 rc 列的棋盘格中可能存在 "蛇" 或 "梯子"。那个蛇或梯子的目的地将会是 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
  • board[i][j] 的值是 -1 或在范围 [1, n2]
  • 编号为 1n2 的方格上没有蛇或梯子

步骤1:定义计算问题性质

  1. 输入:

    • 一个大小为 n×nn \times nn×n 的二维整数矩阵 board
    • 矩阵中的每个元素要么是 -1(无蛇或梯子),要么是一个整数,表示目标方格的编号。
    • board[i][j] 表示棋盘第 iii 行第 jjj 列格子的状态。
  2. 输出:

    • 达到编号为 n2n^2n2 的方格所需的最少掷骰次数。如果无法到达,返回 -1
  3. 约束条件:

    • 2≤n≤202 \leq n \leq 202≤n≤20。
    • 每次掷骰子后,玩家最多可以前进 6 格。
    • 蛇和梯子的起点和终点在棋盘上有对应编号。编号 111 和 n2n^2n2 的格子上没有蛇或梯子。
  4. 潜在边界条件:

    • 棋盘上没有蛇或梯子。
    • 棋盘中存在死循环(多个蛇或梯子互相连接)。
    • n=2n = 2n=2 或 n=20n = 20n=20 的极限大小。

步骤2:问题分解与算法设计

1. 将棋盘映射为一维数组
  • 二维矩阵 boardboardboard 的格子编号从左下角开始,转行交替方式编号。
  • 通过一个辅助函数实现编号和坐标的相互映射,便于后续算法处理。
2. 采用广度优先搜索(BFS)
  • 核心思路:
    • BFS 模拟骰子的移动过程,计算从起点 111 到终点 n2n^2n2 的最少步数。
    • BFS 保证了搜索路径中每一步都是最短路径。
  • 步骤:
    1. 从起点 111 开始。
    2. 模拟掷骰子,每次掷骰后计算目标方格(最多前进 6 格)。
    3. 检查目标方格是否有蛇或梯子,更新位置。
    4. 如果到达终点 n2n^2n2,记录步数并返回。
    5. 如果无法继续前进,返回 -1
3. 复杂度分析
  • 时间复杂度:O(n2)O(n^2)O(n2),每个节点最多访问一次。
  • 空间复杂度:O(n2)O(n^2)O(n2),用于存储访问状态。

步骤3:C++代码实现

cpp 复制代码
class Solution {
public:
    // 辅助函数:将二维坐标映射到一维编号
int getId(int row, int col, int n) {
    if (row % 2 == n % 2) {
        return row * n + (n - 1 - col);
    } else {
        return row * n + col;
    }
}

// 主函数:计算最少掷骰次数
int snakesAndLadders(vector<vector<int>>& board) {
    int n = board.size();
    vector<int> flatBoard(n * n + 1, -1); // 将棋盘展平成一维数组
    int id = 1;

    for (int i = n - 1; i >= 0; --i) {
        for (int j = 0; j < n; ++j) {
            int col = (i % 2 == n % 2) ? n - 1 - j : j;
            flatBoard[id++] = board[i][col];
        }
    }

    queue<pair<int, int>> q; // 队列存储(当前位置,步数)
    vector<bool> visited(n * n + 1, false);
    q.push({1, 0}); // 从起点 1 开始
    visited[1] = true;

    while (!q.empty()) {
        auto [curr, steps] = q.front();
        q.pop();

        for (int dice = 1; dice <= 6; ++dice) {
            int next = curr + dice;
            if (next > n * n) break; // 超出棋盘范围

            if (flatBoard[next] != -1) {
                next = flatBoard[next]; // 遇到蛇或梯子
            }

            if (next == n * n) {
                return steps + 1; // 到达终点
            }

            if (!visited[next]) {
                visited[next] = true;
                q.push({next, steps + 1});
            }
        }
    }

    return -1; // 无法到达终点
}

};

步骤4:解题启发

  1. BFS 的优越性:

    • 广度优先搜索在寻找最短路径问题中十分高效,尤其适合树形或图形结构。
    • 在飞行棋或迷宫问题中,BFS 是一个基础且可靠的算法。
  2. 问题分解的重要性:

    • 本题中棋盘的编号映射是核心,分解问题后算法实现更直观。

步骤5:实际应用场景

  1. 应用场景:飞行棋游戏优化

    • 例如:自动驾驶飞行棋 AI 玩家决策。
    • 实现方法:
      • 使用 BFS 预先计算最优路径。
      • 根据当前棋盘状态调整 AI 策略。
  2. 物流调度路径规划

    • 本算法思想可用于模拟物流配送中的路径规划,特别是有额外加速或延迟条件的复杂网络。
相关推荐
Star Patrick1 分钟前
算法训练(leetcode)二刷第三十五天 | *121. 买卖股票的最佳时机、*122. 买卖股票的最佳时机 II、*123. 买卖股票的最佳时机 III
算法·leetcode·职场和发展
xuchaoxin137527 分钟前
二叉树@基本概念和性质@存储结构
数据结构·算法
M-x_y1 小时前
排序算法--C语言
c语言·算法·排序算法·设计语言
阿里技术1 小时前
HNSW 分布式构建实践
分布式·算法·方案·hnsw·向量检索
南宫生1 小时前
力扣-图论-9【算法学习day.59】
java·学习·算法·leetcode·图论
CopyProfessor1 小时前
Java版-图论-最短路-Floyd算法
java·算法·图论
aaal12341 小时前
代码随想录算法训练营day39|动态规划part7
算法·动态规划
Coding~2 小时前
逆向攻防世界CTF系列56-easy_Maze
c语言·汇编·算法·安全·网络安全
狄加山6753 小时前
C语言(函数)
java·c语言·算法