You are given an array of integers nums of size n and a positive integer threshold.
There is a graph consisting of n nodes with the ith node having a value of
nums[i]. Two nodes i and j in the graph are connected via an
undirected edge if lcm(nums[i], nums[j]) <= threshold.
Return the number of connected components in this graph.
A connected component is a subgraph of a graph in which there exists a path between any two vertices, and no vertex of the subgraph shares an edge with a vertex outside of the subgraph.
The term lcm(a, b) denotes the least common multiple of a and b.
Input: nums =[2,4,8,3,9], threshold =5Output: 4Explanation:

The four connected components are `(2, 4)`,`(3)`,`(8)`,`(9)`.
Input: nums =[2,4,8,3,9,12], threshold =10Output: 2Explanation:

The two connected components are `(2, 3, 4, 8, 9)`, and `(12)`.
If lcm(a, b) ≤ threshold, then both a and b must be divisible by some integer d > threshold / max(a, b). Instead of checking all pairs, we can group numbers by their divisors greater than threshold and union them. Each group forms a connected component.
classSolution {
public:int countComponents(vector<int>& nums, int threshold) {
int n = nums.size();
unordered_map<int, int> idx;
for (int i =0; i < n; ++i) idx[nums[i]] = i;
vector<int> par(n);
iota(par.begin(), par.end(), 0);
function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };
int mx =*max_element(nums.begin(), nums.end());
for (int d = threshold +1; d <= mx; ++d) {
int root =-1;
for (int m = d; m <= mx; m += d) {
if (idx.count(m)) {
if (root ==-1) root = idx[m];
else par[find(idx[m])] = find(root);
}
}
}
unordered_set<int> comps;
for (int i =0; i < n; ++i) comps.insert(find(i));
return comps.size();
}
};
classSolution {
publicintcountComponents(int[] nums, int threshold) {
int n = nums.length;
Map<Integer, Integer> idx =new HashMap<>();
for (int i = 0; i < n; i++) idx.put(nums[i], i);
int[] par =newint[n];
for (int i = 0; i < n; i++) par[i]= i;
int mx = Arrays.stream(nums).max().getAsInt();
for (int d = threshold + 1; d <= mx; d++) {
int root =-1;
for (int m = d; m <= mx; m += d) {
if (idx.containsKey(m)) {
if (root ==-1) root = idx.get(m);
else par[find(par, idx.get(m))]= find(par, root);
}
}
}
Set<Integer> comps =new HashSet<>();
for (int i = 0; i < n; i++) comps.add(find(par, i));
return comps.size();
}
privateintfind(int[] par, int x) {
if (par[x]!= x) par[x]= find(par, par[x]);
return par[x];
}
}
classSolution {
funcountComponents(nums: IntArray, threshold: Int): Int {
val n = nums.size
val idx = nums.withIndex().associate { it.value to it.index }
val par = IntArray(n) { it }
funfind(x: Int): Int {
if (par[x] != x) par[x] = find(par[x])
return par[x]
}
val mx = nums.maxOrNull()!!for (d in threshold + 1..mx) {
var root = -1var m = d
while (m <= mx) {
idx[m]?.let {
if (root == -1) root = itelse par[find(it)] = find(root)
}
m += d
}
}
return (0 until n).map { find(it) }.toSet().size
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
defcountComponents(self, nums: list[int], threshold: int) -> int:
n = len(nums)
idx = {v: i for i, v in enumerate(nums)}
par = list(range(n))
deffind(x):
if par[x] != x:
par[x] = find(par[x])
return par[x]
mx = max(nums)
for d in range(threshold +1, mx +1):
root =-1for m in range(d, mx +1, d):
if m in idx:
if root ==-1:
root = idx[m]
else:
par[find(idx[m])] = find(root)
return len({find(i) for i in range(n)})