leetcode 1631. 最小体力消耗路径(并查集)

你准备参加一场远足活动。给你一个二维 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 。

代码

class Solution {
    class  edge{

        int x,x1,len;

        public edge(int x, int x1, int len) {
            this.x = x;
            this.x1 = x1;
            this.len = len;
        }
    }



    int[] fa;

    public void  init()
    {
        for(int i=0;i<fa.length;i++)
            fa[i]=i;

    }
    public int  find(int x)
    {
        if(x!=fa[x])
          fa[x]=find(fa[x]);
        return fa[x];
    }
    public void   union(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x==y) return;
        fa[x]=y;

    }
    public int minimumEffortPath(int[][] heights) {

        PriorityQueue<edge> priorityQueue=new PriorityQueue<>((o1, o2) -> o1.len-o2.len);
        int r=heights.length,c=heights[0].length;
        for(int i=0;i<r;i++)//将相邻的格子高度差作为边的权重
            for(int j=0;j<c;j++)
            {

                int cur=i*c+j;
                if(i<r-1)
                {
                  priorityQueue.add(new edge(cur,cur+c, Math.abs(heights[i][j]-heights[i+1][j])));

                }
                if(j<c-1)
                {
                    priorityQueue.add(new edge(cur,cur+1, Math.abs(heights[i][j]-heights[i][j+1])));
                }
            }
        fa=new int[r*c];
            init();
            while (!priorityQueue.isEmpty())//不断的加入权重小的边,直到起点和终点连通
            {
                edge cur=priorityQueue.poll();
                union(cur.x,cur.x1);
                if(find(0)==find(r*c-1))
                    return cur.len;
            }
            return 0;

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值