Topic
给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。
连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。
请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。
Example_1
输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
输出:20
解释:
我们可以按照上图所示连接所有点得到最小总费用,总费用为 20 。
注意到任意两个点之间只有唯一一条路径互相到达。
Example_2
输入:points = [[3,12],[-2,5],[-4,1]]
输出:18
Example_3
输入:points = [[0,0],[1,1],[1,0],[-1,1]]
输出:4
Example_4
输入:points = [[-1000000,-1000000],[1000000,1000000]]
输出:4000000
Example_5
输入:points = [[0,0]]
输出:0
Solution:
熟悉并查集和Kruskal算法后很简单就可以看出这是一道典型的Kruskal算法题
不熟悉的同志可以看我之前总结的并查集+Kruskal算法
首先要构造权重边计算权重:
因为Kruskal算法以边为维度
因此需要首先构造所有点两两相连时每条边的权重(这里是边的长度)
同时需要将points中原来的边和权重放在一起放入edges中
之后需要按照权重进行排序
最后通过并查集计算
先实例化并查集并在并查集中构造节点
然后使用并查集构造连通分量
若两个节点已经连接了,跳过
若两个节点未连接
将两个点连接起来
将花费加入结果中
最后返回res即是结果
Code_1
class UnionFind:
def __init__(self):
self.father = {
}
def find(self, x):
root = x
while self.father[root] != None:
root = self.father[root]
# 路径压缩
while x != root:
original_father = self.father[x]
self.father[x] = root
x = original_father
return root
def merge(self, x, y):
root_x,root_y = self.find(x),self.find(y)
if root_x != root_y:
self.father[root_x