为了让每个电脑都能连在网络里,可以移动网线,把没有连接的电脑连起来。
问需要移动多少条网线。
不能做到的话返回-1。
思路:
细观察,这不就是聚类么,
要把单独的类都聚到一个大类里面去。
需要移动的网线数量就是单独的类的个数。
Example1中,电脑3单独成一类,需要移动一根网线。
Example2中,电脑4和5单独成2类,需要移动2根网线。
如果网线不够就返回-1,什么情况下网线不够?
总共有n台电脑,那么至少需要n-1条网线,它们才能全部连起来。
如果网线个数少于n-1, 直接返回-1.
如何聚类呢,用union-find.
最后parent是它自己的就是单独一类的。
但是要排除掉最后聚成一类的那个类本身。
public int makeConnected(int n, int[][] connections) {
if(connections.length < n-1) return -1;
int res = 0;
int[] parent = new int[n];
for(int i = 0; i < n; i++) parent[i] = i;
//union
for(int[] conn : connections) {
int p1 = find(parent, conn[0]);
int p2 = find(parent, conn[1]);
if(p1 == p2) continue;
parent[p2] = p1;
}
for(int i = 0; i < n; i++) {
if(parent[i] == i) res ++;
}
res --; //root本身
return res;
}
int find(int[] parent, int cur) {
int p = cur;
while(parent[p] != p) {
p = parent[p];
parent[p] = parent[parent[p]];
}
return p;
}