给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。
连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。
请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。
示例 1:
输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
输出:20
解释:
我们可以按照上图所示连接所有点得到最小总费用,总费用为 20 。
注意到任意两个点之间只有唯一一条路径互相到达。
示例 2:
输入:points = [[3,12],[-2,5],[-4,1]]
输出:18
示例 3:
输入:points = [[0,0],[1,1],[1,0],[-1,1]]
输出:4
示例 4:
输入:points = [[-1000000,-1000000],[1000000,1000000]]
输出:4000000
示例 5:
输入:points = [[0,0]]
输出:0
提示:
1 <= points.length <= 1000
-106 <= xi, yi <= 106
所有点 (xi, yi) 两两不同。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-cost-to-connect-all-points
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
类似LeetCode-Python-1135. 最低成本联通所有城市,标准最小生成树问题。
时间复杂度:O(N^2)
空间复杂度:O(N^2)
class UnionFindSet(object):
def __init__(self, n):
# m, n = len(grid), len(grid[0])
self.roots = [i for i in range(n + 1)]
self.rank = [0 for i in range(n + 1)]
self.count = n
def find(self, member):
tmp = []
while member != self.roots[member]:
tmp.append(member)
member = self.roots[member]
for root in tmp:
self.roots[root] = member
return member
def union(self, p, q):
parentP = self.find(p)
parentQ = self.find(q)
if parentP != parentQ:
if self.rank[parentP] > self.rank[parentQ]:
self.roots[parentQ] = parentP
elif self.rank[parentP] < self.rank[parentQ]:
self.roots[parentP] = parentQ
else:
self.roots[parentQ] = parentP
self.rank[parentP] -= 1
self.count -= 1
class Solution(object):
def minCostConnectPoints(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
from heapq import *
queue = []
res = 0
n = len(points)
for i in range(n):
for j in range(i + 1, n):
d = abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1])
heappush(queue, (d, i, j))
ufs = UnionFindSet(n)
while ufs.count > 1:
d, i, j = heappop(queue)
if ufs.find(i) != ufs.find(j):
res += d
ufs.union(i, j)
return res