题目
1319. 连通网络的操作次数
用以太网线缆将 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
解释:线缆数量不足。
示例 4:
输入:n = 5, connections = [[0,1],[0,2],[3,4],[2,3]]
输出:0
解法
思路:
这题看题目就知道属于考察并查集。
首先我们得知道,假设有m个点,那至少需要m-1条边才能将所有的点连接起来。
进一步讲,假设有m个连通量,那么一样至少需要m-1条边才能讲所有连同量连接起来。
那这m-1条边从哪来呢?从那m个连通里多余出来的。
所以这题的精髓就是,判断连通量count和多余边excess的关系
如果count-1 <= excess则可以完成连接,需要count-1步,否则返回-1
所以解题步骤如下:
- 按着connections数组将各个点连接,连接的时候判断,当前两个点是否在一个连通量里,如果不在,直接相连,如果在,则多余边双量excess++
- 连接完成后,用当前的连通量数量count和excess比较,如果count<=excess,则可以完成连接,连接次数为count-1
代码如下:
/**
* @param {number} n
* @param {number[][]} connections
* @return {number}
*/
var makeConnected = function(n, connections) {
let len = connections.length;
let parent = new Array(n).fill(0).map((el,index)=>index);
let count = n;
let excess = 0;
for(let i=0;i<len;i++){
let rootP = find(parent,connections[i][0]);
let rootQ = find(parent,connections[i][1]);
if(rootP == rootQ){
excess++;
}else{
union(parent,rootP,rootQ)
count--
}
}
if(count-1 <= excess){
return count-1
}else{
return -1;
}
};
function union(parent,rootP,rootQ){
parent[rootP] = rootQ;
}
function find(parent,x){
if(parent[x] != x){
parent[x] = find(parent,parent[x])
}
return parent[x];
}
复杂度分析
时间复杂度:O(mlogn),遍历connection数组为m,find查找这里做了路径优化,没有做按秩合并,复杂度平均为α(n),最多为logn,故为O(mlogn)。
空间复杂度:O(n),parent数组需要存放所有节点的父子关系。