1631. 最小体力消耗路径

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

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

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


思路:用图进行处理该问题,构建边和相应的权重。按照权重对边进行排序。构建并查集,从最小的边开始构建并查集,若起点和终点可以联通,就返回边的权重。

class Solution {

    int N = 10009;
    // 并查集
    int[] p = new int[N];
    int row, col;
    void union(int a, int b) {
        p[find(a)] = p[find(b)];
    }
    boolean query(int a, int b) {
        return p[find(a)] == p[find(b)];
    }

    int find(int x) {
        if(p[x]!=x) p[x] = find(p[x]);
        return p[x];
    }
    public int minimumEffortPath(int[][] heights) {
        row = heights.length;
        col = heights[0].length;

        // 并查集初始化, 二维转一维
        for(int i=0; i<row*col; i++) {
            p[i] = i;
        }

        List<int[]> edges = new ArrayList();

        for(int i=0; i<row; i++) {
            for(int j=0; j<col; j++) {
                int idx = getIdx(i, j);
                if(i+1<row) {
                    int a = idx, b = getIdx(i+1, j);
                    int w = Math.abs(heights[i][j] - heights[i+1][j]);
                    edges.add(new int[]{a,b,w});
                }

                if(j+1<col) {
                    int a = idx, b = getIdx(i, j+1);
                    int w = Math.abs(heights[i][j] - heights[i][j+1]);
                    edges.add(new int[]{a,b,w});
                }
            }
        }

        Collections.sort(edges, (a,b)->a[2]-b[2]);

        int start = 0, end = getIdx(row-1, col-1);
        for(int [] edge:edges) {
            int a = edge[0], b = edge[1], w = edge[2];
            union(a, b);
            if(query(start, end)) {
                return w;
            }
        }
        return 0;
    }
    int getIdx(int x, int y) {
        return x*col + y;
    }
}

你可能感兴趣的:(java,开发语言)