zoukankan      html  css  js  c++  java
  • Leetcode1631. 最小体力消耗路径

    1631. 最小体力消耗路径

    Difficulty: 中等

    你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights ,其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格子 (0, 0) ,且你希望去最右下角的格子 (rows-1, columns-1) (注意下标从 0 开始编号)。你每次可以往  四个方向之一移动,你想要找到耗费 体力 最小的一条路径。

    一条路径耗费的 体力值 是路径上相邻格子之间 高度差绝对值 的 最大值 决定的。

    请你返回从左上角走到右下角的最小** 体力消耗值** 。

    示例 1:

    输入:heights = [[1,2,2],[3,8,2],[5,3,5]]
    输出:2
    解释:路径 [1,3,5,3,5] 连续格子的差值绝对值最大为 2 。
    这条路径比路径 [1,2,2,2,5] 更优,因为另一条路径差值最大值为 3 。
    

    示例 2:

    输入:heights = [[1,2,3],[3,8,4],[5,3,5]]
    输出:1
    解释:路径 [1,2,3,4,5] 的相邻格子差值绝对值最大为 1 ,比路径 [1,3,5,3,5] 更优。
    

    示例 3:

    输入:heights = [[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]
    输出:0
    解释:上图所示路径不需要消耗任何体力。
    

    提示:

    • rows == heights.length
    • columns == heights[i].length
    • 1 <= rows, columns <= 100
    • 1 <= heights[i][j] <= 10<sup>6</sup>

    Solution

    思路:查找一条路径使该路径代价最小,路径的代价为该路径上最大权的边。首先题目给的是点的信息,需要先将它转化为图,将二维地图的每一个格视为一个点,相邻的格之间有边相连,边权值为两个格的数值差。
    一般我们只要深度遍历或广度遍历图结点计算所有路径的代价即可,但图中点一多就很容易超时,因此,我们转化思路,只要找到一条路径使它从起始点到出发点的代价最小就行,那么我们只要从权重最小的边开始找,当该条边加入图中时能使起点到终点连通,那么该边权重,就是所在路径的代价,也就是要找的结果。
    所以,使用并查集判断图是否连通。当一条边加入图中后,起点到终点连通,而且该边的权重为图中最大权值,所以它就是要找的答案。

    Language: java

    ​class Solution {
        public int minimumEffortPath(int[][] heights) {
            int l = heights.length;
            int w = heights[0].length;
            int[][] edges = new int[2*l*w-l-w][3];
            int idx = 0;
            for(int i=0; i<l; i++){
                for(int j=0; j<w; j++) {
                    if (j > 0) {
                        edges[idx][0] = i*w+j-1;
                        edges[idx][1] = i*w+j;
                        edges[idx++][2] = Math.abs(heights[i][j - 1] - heights[i][j]);
                    }
                    if (i > 0) {
                        edges[idx][0] = i*w+j-w;
                        edges[idx][1] = i*w+j;
                        edges[idx++][2] = Math.abs(heights[i - 1][j] - heights[i][j]);
                    }
                }
            }
            Arrays.sort(edges, Comparator.comparingInt(a -> a[2]));
            UnionFind uf = new UnionFind(l*w);
            int res = 0;
            for(int i=0; i<edges.length; i++){
                uf.merge(edges[i][0], edges[i][1]);
                if(uf.find(0) == uf.find(l*w-1)){
                    res = edges[i][2];
                    break;
                }
            }
            return res;
        }
        class UnionFind{
            int[] parent;
            public UnionFind(int len){
                parent = new int[len];
                for(int i=0; i<len; i++) parent[i] = i;
            }
    
            public int find(int x){
                return parent[x] == x ? x : (parent[x] = find(parent[x]));
            }
    
            public void merge(int x, int y){
                parent[find(y)] = find(x);
            }
        }
    }
    
  • 相关阅读:
    Java中String.valueOf()方法的解释
    React 16.13.1开启严格模式会触发两次render
    React开发中使用react-router-dom路由最新版本V5.1.2(三)路由嵌套子路由
    React开发中使用react-router-dom路由最新版本V5.1.2(二)路由跳转及传参
    React开发中使用react-router-dom路由最新版本V5.1.2(一)基本跳转属性
    vue 开发中实现provide和inject的响应式数据监听
    VUE开发中,数据变化后,修改了绑定对象的属性值后,页面dom没有发生变化,两种方法可以重新渲染$set和$forceUpdate
    VUE开发中.sync 修饰符的作用
    VUE开发中.native 修饰符的作用
    git报错:CONFLICT (modify/delete) ,git冲突,解决项目开发中改了相同文件同一行
  • 原文地址:https://www.cnblogs.com/liuyongyu/p/14347763.html
Copyright © 2011-2022 走看看