Leetcode 1584. Min Cost to Connect All Points
题目
错误解法:
最开始以为通过判断加入的边的数量和被访问过的点的数量可以判断是不是符合条件了,其实这样是不成立的,可以举出很多反例
class Solution(object):
def minCostConnectPoints(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
d2p = collections.defaultdict(list)
d_vec = []
for i in range(len(points)):
for j in range(i+1,len(points)):
p1 = points[i]
p2 = points[j]
dis = abs(p1[0]-p2[0])+abs(p1[1]-p2[1])
d2p[dis].append((i,j))
d_vec.append(dis)
#print(d2p)
d_vec.sort()
#print(d_vec)
visited = set()
ans = 0
for dis in d_vec:
for pair in d2p[dis]:
if pair[0] not in visited or pair[1] not in visited:
ans += dis
visited.add(pair[0])
visited.add(pair[1])
#print(points[pair[0]],points[pair[1]])
#print(dis)
if len(visited)==len(points):
return ans
return 0
解法:Minimum spanning tree
其实这个题目是最小生成树的一个典型代表。给一系列的点,spanning tree指的是能将他们全部联通的情况。而minimum在这道题目指的是所有spanning tree中边的和最小的情况
参考这里:https://www.hackerearth.com/practice/algorithms/graphs/minimum-spanning-tree/tutorial/
这边实现minimum spanning可以使用union find。因为当我们考虑一条边时,是不是加入这条边的判断是基于他们是否在一个连通图中,或者一个cluster中,这个很显然可以用并查集
这边值得一提的是,如果当我们加入的边等于点数减1的时候,因为我们使用了并查集,所以可以保证所有的点都已经被联通了。因为对于几个点,把他们联通的最小边数是点数减一
union find + sort
class Solution(object):
def minCostConnectPoints(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
# standard definition of union find
def find(p):
while p != roots[p]:
p = roots[p]
return p
def union(p,q):
roots[find(p)] = find(q)
roots = list(range(len(points)))
graph = []
for i in range(len(points)):
for j in range(i+1,len(points)):
dis = abs(points[i][0]-<