3286、穿越网格图的安全路径

3286、[中等] 穿越网格图的安全路径

1、题目描述

给你一个 m x n 的二进制矩形 grid 和一个整数 health 表示你的健康值。你开始于矩形的左上角 (0, 0) ,你的目标是矩形的右下角 (m - 1, n - 1) 。你可以在矩形中往上下左右相邻格子移动,但前提是你的健康值始终是 正数

对于格子 (i, j) ,如果 grid[i][j] = 1 ,那么这个格子视为 不安全 的,会使你的健康值减少 1 。如果你可以到达最终的格子,请你返回 true ,否则返回 false

注意 ,当你在最终格子的时候,你的健康值也必须为 正数

2、解题思路

这个问题可以通过图的最短路径算法来解决。我们需要使用一个动态规划 (DP) 方法来记录从起点到每个位置所需的最小健康值。在这个问题中,我们可以将 DP 结合 DFS 来实现。

详细步骤

  1. 初始化
    • 创建一个二维 DP 数组 dp,用于记录从起点 (0, 0) 到每个位置 (i, j) 所需的最小健康值。
    • 将 DP 数组初始化为 INT_MAX(一个非常大的数),表示未访问的状态。起点 (0, 0) 的 DP 值初始化为 grid[0][0],即起点的健康消耗值。
  2. DFS 遍历
    • 使用 DFS 遍历矩阵中的每个位置 (i, j)
    • 对于每个位置 (i, j),尝试向四个方向移动,检查是否可以到达邻居格子,并更新其 DP 值。
    • 如果到达新位置的最小健康值小于当前已知值,则更新 DP 值,并继续从该位置进行 DFS 遍历。
  3. 结束条件
    • 最后检查 DP 数组中终点 (m-1, n-1) 的值是否小于初始健康值 health。如果是,则表示可以在健康值大于 0 的情况下到达终点。

3、代码实现

#include <vector>
#include <limits.h>

using namespace std;

class Solution {
private:
    int pos[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上、下、左、右方向

public:
    bool findSafeWalk(vector<vector<int>>& grid, int health) {
        int row = grid.size();
        int col = grid[0].size();
        vector<vector<int>> dp(row, vector<int>(col, INT_MAX));
        dp[0][0] = grid[0][0]; // 起点的健康消耗

        dfs(grid, dp, row, col, 0, 0); // 从起点开始进行 DFS

        return dp[row - 1][col - 1] < health; // 检查终点的最小健康值
    }

    void dfs(vector<vector<int>>& grid, vector<vector<int>>& dp, int row, int col, int i, int j) {
        for (int k = 0; k < 4; k++) { // 四个方向
            int x = i + pos[k][0];
            int y = j + pos[k][1];

            if (x >= 0 && x < row && y >= 0 && y < col) { // 检查边界
                if (dp[x][y] > dp[i][j] + grid[x][y]) { // 更新 DP 值
                    dp[x][y] = dp[i][j] + grid[x][y];
                    dfs(grid, dp, row, col, x, y); // 继续 DFS
                }
            }
        }
    }
};

这个解法结合了 DFS 和动态规划,通过在矩阵中维护最小健康值来确保从起点到终点的路径在健康值条件下是可行的。

相关推荐
ULTRA??4 分钟前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
凌云行者39 分钟前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
凌云行者43 分钟前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
可均可可2 小时前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
幸运超级加倍~2 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
白子寰2 小时前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
yannan201903132 小时前
【算法】(Python)动态规划
python·算法·动态规划