两数有共同的大于1的公因数时,就在二者画一条边,问图的最大连通子图的大小。
如果将数的因子作为根节点,把数一个个的挂上去,可以用并查集。
参考自:大佬的题解
class Solution {
public int largestComponentSize(int[] A) {
int maxvalue = Integer.MIN_VALUE;
for (int num : A) // 以数组中最a大的元素为标准开数组
maxvalue = Math.max(maxvalue, num);
Check_And_Set cas = new Check_And_Set(maxvalue + 1);
for (int num : A) {
double upBound = Math.sqrt(num);
//求出每个数的大于1因子,并将数挂到相应的因子根节点上
for (int i = 2; i <= upBound; i++) {
if (num % i == 0) {
cas.union(num, i);
cas.union(num, num / i);
}
}
}
// 将候选数组映射成代表元,统计代表元出现的次数,找出最大者
int[] cnt = new int[maxvalue + 1];
int res = 0;
for (int num : A) {
int root = cas.find(num); //找到根节点
cnt[root]++;
res = Math.max(res, cnt[root]);
}
return res;
}
class Check_And_Set { // 并查集类
int[] parent;
public Check_And_Set(int n) {
parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
// 用递归来找祖先节点
public int find(int x) {
while (parent[x] != x) {
parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
}
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY)
parent[rootX] = rootY;
}
}
}