leetcode 1631. Path With Minimum Effort(最小消耗路径)

本文介绍如何利用Dijkstra算法求解从矩阵左上角到右下角的最短路径问题,路径成本由相邻点高度差的绝对值决定,目标是找到总成本最大的路径。通过调整边的权重计算和优先队列策略,实现高效路径搜索。

在这里插入图片描述

从(0, 0) 到 矩阵右下角 找出一条最短路径,
注意路径的cost不是数字的和,而是这条路径上每两个相邻点的差有个绝对值,路径的cost定义为这些差的绝对值中最大的。每个路径对应一个cost。
在所有路径中找出cost最小的。返回cost。

思路

我们知道最短路径算法有Dijkstra算法,
dist[v]表示从起点(0, 0)到点v的距离,cost(u, v)表示点u到点v的距离。
如果途中经过u点,那么dist[v] = dist[u] + cost(u, v)

Dijkstra算法是这么个流程:

dist数组初始化为最大值。

从起点(0, 0)出发,计算从(0,0)点到与它相连的所有点的距离,
如果(0, 0)到点v的距离cost[v] < dist[v],那么更新dist[v] = cost[v]
并把(v, dist[v])装入优先队列。

下次从优先队列中取出dist最小的,再从取出的点出发,重复上面的过程,直到优先队列中没有点。

思想就是每次取出从起点到现在路径最短的点,以这个点为中转点,计算它到下一个点的距离,并更新最小距离。

当然上面的算法基于的距离是边的权重,那我们这里如何定义边的权重呢,

假如现在从u点出发,那么与它连接(有边)的点 v 就是它的上下左右四个点,
边的权重就是两个点的height差的绝对值,记为cost。

因为路径的COST是每步cost(差的绝对值)中最大的那个,所以只需要把cost和dist[u]相比,取较大的那个,
也就是cost[v] = max(dist[u], cost),

但是假如计算出来的cost[v]比之前保存的dist[v]大,也就是说当前不是最优路径,那么直接丢弃,不再保存到优先队列,也不更新dis[v]。
如果是最优路径,cost[v] < dist[v], 那么更新dist[v] = cost[v],
并把(v, dist[v])存入优先队列。

下次从优先队列中取出dist最小的,重复上面的过程,直到优先队列中不再有值。

*注意这里的cost是计算整个路径COST时其中的一步,而整个路径COST是所有这些cost中最大的。
计算每条路径COST时取cost最大,最后从众多路径中选择的时候取COST最小。

public int minimumEffortPath(int[][] heights) {
    int[] move = new int[]{-1, 0, 1, 0, -1};
    
    int rows = heights.length;
    int cols = heights[0].length;
    
    PriorityQueue<Pair<Integer, Integer>> queue = new PriorityQueue<>((a, b)->(a.getValue() - b.getValue()));
    int[] dist = new int[rows * cols];
    Arrays.fill(dist, Integer.MAX_VALUE); //起点(0,0)到当前点的距离
    
    dist[0] = 0;
    queue.offer(new Pair(0, 0));
    
    while(!queue.isEmpty()) {
        Pair<Integer, Integer> cur = queue.poll();
        int idx = cur.getKey().intValue();
        int cost = cur.getValue().intValue();
        if(idx == rows * cols - 1) return cost;
        if(cost > dist[idx]) continue;
        int r = idx / cols;
        int c = idx % cols;
        
        for(int i = 0; i < 4; i++) {
            int curR = r + move[i];
            int curC = c + move[i+1];
            if(curR < 0 || curC < 0 || curR >= rows || curC >= cols) continue;
            int curIdx = curR * cols + curC;
            int curCost = Math.abs(heights[curR][curC] - heights[r][c]);
            if(Math.max(cost, curCost) >= dist[curIdx]) continue;
            dist[curIdx] = Math.max(cost, curCost);
            queue.offer(new Pair<Integer, Integer>(curIdx, dist[curIdx]));
        }
    }
    return 0;
}
### 如何在 VSCode 中安装和配置 LeetCode 插件以及 Node.js 运行环境 #### 安装 LeetCode 插件 在 VSCode 的扩展市场中搜索 `leetcode`,找到官方提供的插件并点击 **Install** 按钮进行安装[^1]。如果已经安装过该插件,则无需重复操作。 #### 下载与安装 Node.js 由于 LeetCode 插件依赖于 Node.js 环境,因此需要下载并安装 Node.js。访问官方网站 https://nodejs.org/en/ 并选择适合当前系统的版本(推荐使用 LTS 版本)。按照向导完成安装流程后,需确认 Node.js 是否成功安装到系统环境中[^2]。 可以通过命令行运行以下代码来验证: ```bash node -v npm -v ``` 上述命令应返回对应的 Node.js 和 npm 的版本号。如果没有正常返回版本信息,则可能未正确配置环境变量。 #### 解决环境路径问题 即使完成了 Node.js 的安装,仍可能出现类似 “LeetCode extension needs Node.js installed in environment path” 或者 “command ‘leetcode.toggleLeetCodeCn’ not found” 的错误提示[^3]。这通常是因为 VSCode 未能识别全局的 Node.js 路径或者本地安装的 nvm 默认版本未被正确加载[^4]。 解决方法如下: 1. 手动指定 Node.js 可执行文件的位置 在 VSCode 设置界面中输入关键词 `leetcode`,定位至选项 **Node Path**,将其值设为实际的 Node.js 安装目录下的 `node.exe` 文件位置。例如:`C:\Program Files\nodejs\node.exe`。 2. 使用 NVM 用户管理工具调整默认版本 如果通过 nvm 工具切换了不同的 Node.js 版本,请确保设置了默认使用的版本号。可通过以下指令实现: ```bash nvm alias default <version> ``` 重新启动 VSCode 后测试功能键是否恢复正常工作状态。 --- #### 配置常用刷题语言 最后一步是在 VSCode 设置面板中的 LeetCode 插件部分定义个人习惯采用的主要编程语言作为默认提交方式之一。这样可以减少频繁修改编码风格的时间成本。 --- ### 总结 综上所述,要在 VSCode 上顺利启用 LeetCode 插件及其关联服务,除了基本插件本身外还需额外准备支持性的后台框架——即 Node.js 应用程序引擎;同时针对特定场景下产生的兼容性障碍采取针对性措施加以修正即可达成目标[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值