题目介绍
用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。
网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。
给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。
示例 1:
输入:n = 4, connections = [[0,1],[0,2],[1,2]] 输出:1 解释:拔下计算机 1 和 2 之间的线缆,并将它插到计算机 1 和 3 上。 示例 2:
输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]] 输出:2 示例 3:
输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2]] 输出:-1 解释:线缆数量不足。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/nu… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
并查集思路
1.先判断线的数量是否比计算机数量 - 1还小,如果是线的数量不够返回-1 2.创建并查集,遍历connections,归类计算机集合 3.再次遍历connections统计有多少个计算机的集合,返回集合数量 - 1
代码
/**
* @param {number} n
* @param {number[][]} connections
* @return {number}
*/
class UnionSet {
constructor(n) {
this.fa = new Array(n + 1)
for (let i = 0; i <= n; i++) {
this.fa[i] = i
}
}
get(x) {
let fa = this.fa
return fa[x] = (fa[x] === x ? x : this.get(fa[x]))
}
merge(a, b) {
this.fa[this.get(a)] = this.get(b)
}
}
var makeConnected = function(n, connections) {
// 长度代表有多少条线
let m = connections.length
//
if (m < n -1) return -1
let u = new UnionSet(n)
for (let i = 0; i < m; i++) {
let [a, b] = connections[i]
// 相当于归类计算机集合
u.merge(a, b)
}
let ans = 0
for (let i = 0; i < n; i++) {
if (u.get(i) === i) ans += 1
}
return ans - 1
};