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 和动态规划,通过在矩阵中维护最小健康值来确保从起点到终点的路径在健康值条件下是可行的。

相关推荐
m0_6312704032 分钟前
标准C++(二)
开发语言·c++·算法
沫刃起35 分钟前
Codeforces Round 972 (Div. 2) C. Lazy Narek
数据结构·c++·算法
DdddJMs__13536 分钟前
C语言 | Leetcode C语言题解之第413题等差数列划分
c语言·leetcode·题解
爱coding的橙子41 分钟前
CCF-CSP认证考试准备第十五天 202303-3 LDAP
算法
GZM8888882 小时前
配置VS Code以进行C/C++编程:深入探讨与实操指南
c++
martian6652 小时前
学懂C++(六十):C++ 11、C++ 14、C++ 17、C++ 20新特性大总结(万字详解大全)
开发语言·c++·c++20
QXH2000002 小时前
Leetcode—环形链表||
c语言·数据结构·算法·leetcode·链表
小灰灰爱代码3 小时前
C++——判断year是不是闰年。
数据结构·c++·算法
小灰灰爱代码3 小时前
C++——求3个数中最大的数(分别考虑整数、双精度数、长整数数的情况),用函数重载方法。
数据结构·c++·算法
Wils0nEdwards3 小时前
Leetcode 缺失的第一个正整数
leetcode