我的博客

leetcode 周赛 171 5309. 连通网络的操作次数 Number of Operations to Make Network Connected

目录
  1. 解答

赛题链接 英文赛题 题库题目链接

用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 ab

网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。

给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。

示例 1:

img

1
2
3
输入:n = 4, connections = [[0,1],[0,2],[1,2]]
输出:1
解释:拔下计算机 1 和 2 之间的线缆,并将它插到计算机 1 和 3 上。

示例 2:

img

1
2
输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]]
输出:2

示例 3:

1
2
3
输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2]]
输出:-1
解释:线缆数量不足。

示例 4:

1
2
输入:n = 5, connections = [[0,1],[0,2],[3,4],[2,3]]
输出:0

提示:

  • 1 <= n <= 10^5
  • 1 <= connections.length <= min(n*(n-1)/2, 10^5)
  • connections[i].length == 2
  • 0 <= connections[i][0], connections[i][1] < n
  • connections[i][0] != connections[i][1]
  • 没有重复的连接。
  • 两台计算机不会通过多条线缆连接。

解答

我使用并查集方法做,思路简单(我的博客中并查集标签

fa 数组存放每个节点的父亲,sz 存放每个节点树上的儿子大小。

通过查看树根的 sz ,可以知道当前的集合中有多少计算机,如果最大集合中的计算机数量等于 n,那么整个网络就联通了。

算法过程:

初始化并查集

初始化冗余网线数量 :redundancy = 0
当前最大集合中计算机数: cur_max_net_size = 1
当前最大集合的树根: cur_max_net_fa = 0

  1. 首先遍历 connections。对于每一个连接,先看看,连接的两台计算机是否已经联通了:

    1. 如果没有就用并查集的 merge 操作合并两个计算机所在集合,并且获得集合中计算机数量,如果这个数量等于 n 了,就说明至此,网络就全联通了,直接返回 0 ,算法结束
    2. 如果已经联通了,说明这个连接冗余了。这根网线就不用插了,直接把冗余网线数量加一
  2. 到这里没返回说明网络还没联通,这次遍历所有计算机,如果:

    1. 一台计算机已经属于当前最大网络了,不执行任何操作

    2. 一台计算机不属于当前最大网络,首先检查是否还有剩余网线(redundancy):

      1. 如果没有剩余网线,说明无法完成任务,返回 -1
      2. 如果有剩余网线,把当前计算机 merge 到最大网络,操作数(result)加一,并查看最大网络计算机数是否是 n,如果是 n 接结束,返回当前操作数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Solution:
def makeConnected(self, n: int, connections: List[List[int]]) -> int:
fa = [i for i in range(n)]
sz = [1 for i in range(n)]
def getfa(x):
if (fa[x] == x): return x
fa[x] = getfa(fa[x])
return fa[x]
def merge(x, y):
fx = getfa(x)
fy = getfa(y)
if fx == fy: return sz[fx], fx
if sz[fx] > sz[fy]:
fa[fy] = fx
sz[fx] += sz[fy]
return sz[fx], fx
else:
fa[fx] = fy
sz[fy] += sz[fx]
return sz[fy], fy
redundancy = 0
cur_max_net_size = 1
cur_max_net_fa = 0
for x, y in connections:
fx = getfa(x)
fy = getfa(y)
if fx != fy:
cur_size, cur_fa = merge(x, y)
if cur_size > cur_max_net_size:
cur_max_net_size = cur_size
cur_max_net_fa = cur_fa
if cur_size == n:
return 0
else:
redundancy += 1
result = 0
for i in range(n):
fi = getfa(i)
if fi != cur_max_net_fa:
redundancy -= 1
if redundancy < 0:
return -1
result += 1
cur_size, cur_fa = merge(i, cur_max_net_fa)
if cur_size == n:
return result

评论无需登录,可以匿名,欢迎评论!