If two numbers share a common factor greater than 1, they should be in the same component. We can use union-find to group numbers by their factors. For each number, union it with all its factors greater than 1. The largest component is the one with the most numbers.
classSolution {
public:int largestComponentSize(vector<int>& nums) {
int n =*max_element(nums.begin(), nums.end());
vector<int> par(n+1);
iota(par.begin(), par.end(), 0);
function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };
for (int x : nums) {
for (int f =2; f * f <= x; ++f) {
if (x % f ==0) {
par[find(x)] = find(f);
par[find(x)] = find(x/f);
}
}
}
unordered_map<int, int> cnt;
int ans =0;
for (int x : nums) ans = max(ans, ++cnt[find(x)]);
return ans;
}
};
classSolution {
publicintlargestComponentSize(int[] nums) {
int n = Arrays.stream(nums).max().getAsInt();
int[] par =newint[n+1];
for (int i = 0; i <= n; ++i) par[i]= i;
for (int x : nums) {
for (int f = 2; f * f <= x; ++f) {
if (x % f == 0) {
union(par, x, f);
union(par, x, x/f);
}
}
}
Map<Integer, Integer> cnt =new HashMap<>();
int ans = 0;
for (int x : nums) {
int fx = find(par, x);
cnt.put(fx, cnt.getOrDefault(fx, 0) + 1);
ans = Math.max(ans, cnt.get(fx));
}
return ans;
}
privateintfind(int[] par, int x) {
if (par[x]!= x) par[x]= find(par, par[x]);
return par[x];
}
privatevoidunion(int[] par, int x, int y) {
par[find(par, x)]= find(par, y);
}
}
classSolution {
funlargestComponentSize(nums: IntArray): Int {
val n = nums.maxOrNull()!!val par = IntArray(n+1) { it }
funfind(x: Int): Int = if (par[x] == x) x else { par[x] = find(par[x]); par[x] }
for (x in nums) {
var f = 2while (f * f <= x) {
if (x % f ==0) {
par[find(x)] = find(f)
par[find(x)] = find(x/f)
}
f++ }
}
val cnt = mutableMapOf<Int, Int>()
var ans = 0for (x in nums) {
val fx = find(x)
cnt[fx] = cnt.getOrDefault(fx, 0) + 1 ans = maxOf(ans, cnt[fx]!!)
}
return ans
}
}
classSolution:
deflargestComponentSize(self, nums: list[int]) -> int:
n = max(nums)
par = list(range(n+1))
deffind(x: int) -> int:
if par[x] != x:
par[x] = find(par[x])
return par[x]
for x in nums:
for f in range(2, int(x**0.5)+1):
if x % f ==0:
par[find(x)] = find(f)
par[find(x)] = find(x//f)
cnt = {}
ans =0for x in nums:
fx = find(x)
cnt[fx] = cnt.get(fx, 0) +1 ans = max(ans, cnt[fx])
return ans
impl Solution {
pubfnlargest_component_size(nums: Vec<i32>) -> i32 {
let n =*nums.iter().max().unwrap() asusize;
letmut par: Vec<usize>= (0..=n).collect();
fnfind(par: &mut Vec<usize>, x: usize) -> usize {
if par[x] != x { par[x] = find(par, par[x]); }
par[x]
}
for&x in&nums {
letmut f =2;
while f * f <= x {
if x % f ==0 {
let fx = find(&mut par, x asusize);
let ff = find(&mut par, f asusize);
par[fx] = ff;
let fx = find(&mut par, x asusize);
let ff = find(&mut par, (x/f) asusize);
par[fx] = ff;
}
f +=1;
}
}
letmut cnt = std::collections::HashMap::new();
letmut ans =0;
for&x in&nums {
let fx = find(&mut par, x asusize);
let c = cnt.entry(fx).or_insert(0);
*c +=1;
if*c > ans { ans =*c; }
}
ans
}
}
⏰ Time complexity: O(n * sqrt(M)), where n is the length of nums and M is the maximum value in nums. For each number, we check all its factors up to sqrt(M).
🧺 Space complexity: O(M), for the union-find parent array and counting map.