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 。
    在这里插入图片描述

思路

1、并查集
  • 并查集初始化
    二维矩阵初始化为一维列表,长度为rows x columns,比较好理解;
  • 并查集合并
    heights 格子里的任意一个点都可以上下左右移动,上即对下,左也对右,两点之间连接任选上下一个,左右一个就可以;此处选择右,和下,对应的便捷条件就是row-1, col-1;找到所有的连线后按照两点之间的高度差排序,从小到大,进行并查集合并
  • 并查集查找
    截止条件就是当某两点之间合并后,最左上角的格子 (0, 0) 和 最右下角的格子 (rows-1, columns-1)属于同一阵营,就是m.find(row*col-1) == m.find(0);

代码实现

1、并查集
class Model():
    def __init__(self, n):
        self.uset = [i for i in range(n)]
    
    def find(self, x):
        if x != self.uset[x]:
            self.uset[x] = self.find(self.uset[x])
        return self.uset[x]
    
    def union(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        self.uset[fy] = fx

class Solution:
    def minimumEffortPath(self, heights: List[List[int]]) -> int:
        row = len(heights)
        col = len(heights[0])
        m = Model(row*col)
        if len(m.uset) <= 1:
            return 0
        res = []
        for i in range(row):
            for j in range(col):
                temp_index = j + i * col
                if i < row-1:
                    temp_indey = temp_index+col
                    res.append([temp_indey, temp_index, abs(heights[i][j]-heights[i+1][j])])
                if j < col-1:
                    temp_indey = temp_index+1
                    res.append([temp_indey, temp_index, abs(heights[i][j]-heights[i][j+1])])
        res.sort(key=lambda x:x[-1])
        for y, x, val in res:
            m.union(y, x)
            if m.find(row*col-1) == m.find(0):
                # print(x, y, val)
                return val
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值