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