力扣1631最小體力消耗路徑——python
阿新 • • 發佈:2021-01-31
我們先理解一下題目,他要求我們返回的是最小的體力消耗,這裡的體力消耗於高度差的絕對值有關,越小越省體力,我們我們最後需要把所有的內容全部都連線一起。我們可以嘗試用暴力方法求解。
我們依次遍歷上下左右,每條路都求完,然後返回出最大的絕對值之差。
heights = []
r, c = len(heights), len(heights[0])
if r ==1 and c == 1:
return 0
#如果只有一個格子直接返回0
dp = [[float('inf')]*c for _ in range(r)]
#我們建立一個和圖相等的二維列表,用於儲存高度絕對值
res = float('inf')
moves = [[-1, 0], [1, 0], [0, -1], [0, 1]]
#準備好各個方向的走向
q = [[0, 0]]
#設定起點座標
dp[0][0] = 0
#開始的時候為0
while True:
new_q = []
while len(q) >0:
p = q[0]
q = q[1:]#後續還需要走的座標
for move in moves:
new_r, new_c = p[0] + move[0], p[1] + move[1]#我們走過之後的座標
if new_r >= 0 and new_r < r and new_c >=0 and new_c < c:#是否在表格裡面
new_diff = abs(heights[new_r][new_c]-heights[p[0]][p[1]])
#我們求出高度差的絕對值,之後再與這條路上的比較,我們取最大值
new_diff = max(new_diff, dp[p[0]][p[1]])
if new_c == c-1 and new_r == r-1 and new_diff <res:
#判斷是否到達終點,與是否更新最大值
res = new_diff
if res == 0:
return 0
elif new_diff < dp[new_r][new_c]:
#否則的話我們需要修改絕對值的較小值,因為我們需要走較小的值
dp[new_r][new_c] = new_diff
new_q.append([new_r, new_c])
#加入到新的起點繼續遍歷
if len(new_q) == q:
#遍歷完成後返回
return res
q = new_q
除此之外,還有一種更利於理解的題目,就是利用並查集解決,這時候我們需要對列表進行排序,按照高度絕對值排序,優先最小值
什麼是並查集
class UnionFind(object):
#並查集模板
def __init__(self):
self.parent = [i for i in range(10001)]
def find(self, x):
if x != self.parent[x]:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self,x1, x2):
root_x, root_y = self.find(x1), self.find(x2)
self.parent[root_x] = root_y
def is_connected(self, p, q):
return self.find(p) == self.find(q)
class Solution:
def minimumEffortPath(self, heights: List[List[int]]) -> int:
M = len(heights)
N = len(heights[0])
uf = UnionFind()
edges = []
for i in range(M):
for j in range(N):
pos = i * N + j
if i < M - 1:
edges.append([abs(heights[i + 1][j] - heights[i][j]), pos, pos + N])
if j < N - 1:
edges.append([abs(heights[i][j + 1] - heights[i][j]), pos, pos + 1])
edges.sort()
#我們對新的列表排序,好方便我們從小的開始
for edge in edges:
uf.union(edge[1], edge[2])
if uf.is_connected(0, M * N - 1):
#如果兩端相連,說明連線成功,返回此時的高度絕對值就是最小體力消耗中的最大高度絕對值
return edge[0]
return 0