@author=YHR | 转载请标明来源
class Solution:
def __init__(self):
self.inf = int(1e6 + 1)
def minimumEffortPath(self, heights):
self.rows = len(heights)
if self.rows > 0:
self.cols = len(heights[0])
if self.cols > 0:
aim = self.rows * self.cols - 1
start = 0
Dist = self.Dijstra(heights, start)
return Dist[aim]
return 0
def getRowAndColByIndex(self, index):
row = index // self.cols
col = index % self.cols
return row, col
def Dijstra(self, heights, start):
totalNodesNum = self.rows * self.cols
dir = [[0, -1], [0, 1], [-1, 0], [1, 0]]
hasSeen = [0] * totalNodesNum # 0表示未遍历,1表示已经纳入了遍历
# intial the distance from start to others
Dist = [self.inf] * totalNodesNum;
Dist[start] = 0
import heapq
# initial the sorted queue
candidate = []
heapq.heapify(candidate)
heapq.heappush(candidate, [Dist[start], start])
while len(candidate) > 0:
[Dist2nownode, nownode] = heapq.heappop(candidate)
if hasSeen[nownode] == 1:
continue
else:
hasSeen[nownode] = 1
now_r, now_c = self.getRowAndColByIndex(nownode)
for _ in range(4):
new_r = now_r + dir[_][0]
new_c = now_c + dir[_][1]
if 0 <= new_r < self.rows and 0 <= new_c < self.cols:
if hasSeen[new_r * self.cols + new_c] != 1:
if Dist[new_r * self.cols + new_c] > max(Dist2nownode,
abs(heights[now_r][now_c] - heights[new_r][new_c])):
Dist[new_r * self.cols + new_c] = max(Dist2nownode,
abs(heights[now_r][now_c] - heights[new_r][new_c]))
heapq.heappush(candidate, [Dist[new_r * self.cols + new_c], new_r * self.cols + new_c])
return Dist
import heapq
class Solution:
def __init__(self):
self.inf = int(1e6 + 1)
def minimumEffortPath(self, heights):
self.rows = len(heights)
if self.rows > 0:
self.cols = len(heights[0])
if self.cols > 0:
self.totalNodeNums = self.rows * self.cols
return self.unionAndSearchWithKruskal(heights, self.totalNodeNums-1)
return 0
def getRowAndColByIndex(self, index):
row = index // self.cols
col = index % self.cols
return row, col
def getEdges(self, heights):
edges = []
heapq.heapify(edges) # sort by element 0, small heap
# kruskal 获取边
for _ in range(self.totalNodeNums):
this_r, this_c = self.getRowAndColByIndex(_)
# 获取到右边 边
if this_c < self.cols-1:
next_r , next_c = this_r, this_c+1
heapq.heappush(edges, [abs(heights[next_r][next_c] - heights[this_r][this_c]), _, next_r*self.cols + next_c])
# 获取到下面 边
if this_r < self.rows-1:
next_r , next_c = this_r+1, this_c
heapq.heappush(edges, [abs(heights[next_r][next_c] - heights[this_r][this_c]), _, next_r*self.cols + next_c])
return edges
def findRoot(self, parentDict, node):
parent = parentDict[node]
while parent != node:
node = parent
parent = parentDict[node]
return parent
def unionAndSearchWithKruskal(self, heights, aim):
parentDict = [_ for _ in range(self.totalNodeNums)]
size = [1]*self.totalNodeNums
candidate_edges = self.getEdges(heights)
if len(candidate_edges) == 0:
return 0
while len(candidate_edges) > 0:
[edgeweight, startId, endId] = heapq.heappop(candidate_edges)
start_parent = self.findRoot(parentDict, startId)
end_parent = self.findRoot(parentDict, endId)
if start_parent != end_parent:
# 没有成环才考虑加入边
if size[start_parent] < size[end_parent]:
start_parent, end_parent = end_parent, start_parent
parentDict[end_parent] = start_parent
size[start_parent] += size[end_parent] # !!!! 易错点1, 算人头,是把对方麾下的人头都算进来
if self.findRoot(parentDict, aim) == self.findRoot(parentDict, 0):
# # !!!! 易错点2 比较联通是比较他俩祖先是否一样,有可能0的祖先是别人呢!!!!
return edgeweight # 直接返回weight就可以,因为边是从小到大排序,加入这条边,他俩才联通,说明这条边是必须边!