Welcome to Subscribe On Youtube
3378. Count Connected Components in LCM Graph
Description
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
.
Example 1:
Input: nums = [2,4,8,3,9], threshold = 5
Output: 4
Explanation:
The four connected components are (2, 4)
, (3)
, (8)
, (9)
.
Example 2:
Input: nums = [2,4,8,3,9,12], threshold = 10
Output: 2
Explanation:
The two connected components are (2, 3, 4, 8, 9)
, and (12)
.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 109
- All elements of
nums
are unique. 1 <= threshold <= 2 * 105
Solutions
Solution 1
-
class DSU { private Map<Integer, Integer> parent; private Map<Integer, Integer> rank; public DSU(int n) { parent = new HashMap<>(); rank = new HashMap<>(); for (int i = 0; i <= n; i++) { parent.put(i, i); rank.put(i, 0); } } public void makeSet(int v) { parent.put(v, v); rank.put(v, 1); } public int find(int x) { if (parent.get(x) != x) { parent.put(x, find(parent.get(x))); } return parent.get(x); } public void unionSet(int u, int v) { u = find(u); v = find(v); if (u != v) { if (rank.get(u) < rank.get(v)) { int temp = u; u = v; v = temp; } parent.put(v, u); if (rank.get(u).equals(rank.get(v))) { rank.put(u, rank.get(u) + 1); } } } } class Solution { public int countComponents(int[] nums, int threshold) { DSU dsu = new DSU(threshold); for (int num : nums) { for (int j = num; j <= threshold; j += num) { dsu.unionSet(num, j); } } Set<Integer> uniqueParents = new HashSet<>(); for (int num : nums) { if (num > threshold) { uniqueParents.add(num); } else { uniqueParents.add(dsu.find(num)); } } return uniqueParents.size(); } }
-
typedef struct DSU { unordered_map<int, int> par, rank; DSU(int n) { for (int i = 0; i < n; ++i) { par[i] = i; rank[i] = 0; } } void makeSet(int v) { par[v] = v; rank[v] = 1; } int find(int x) { if (par[x] == x) { return x; } return par[x] = find(par[x]); } void unionSet(int u, int v) { u = find(u); v = find(v); if (u != v) { if (rank[u] < rank[v]) swap(u, v); par[v] = u; if (rank[u] == rank[v]) rank[u]++; } } } DSU; class Solution { public: int countComponents(vector<int>& nums, int threshold) { DSU dsu(threshold); for (auto& num : nums) { for (int j = num; j <= threshold; j += num) { dsu.unionSet(num, j); } } unordered_set<int> par; for (auto& num : nums) { if (num > threshold) { par.insert(num); } else { par.insert(dsu.find(num)); } } return par.size(); } };
-
class DSU: def __init__(self, n): self.parent = {i: i for i in range(n)} self.rank = {i: 0 for i in range(n)} def make_set(self, v): self.parent[v] = v self.rank[v] = 1 def find(self, x): if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union_set(self, u, v): u = self.find(u) v = self.find(v) if u != v: if self.rank[u] < self.rank[v]: u, v = v, u self.parent[v] = u if self.rank[u] == self.rank[v]: self.rank[u] += 1 class Solution: def countComponents(self, nums, threshold): dsu = DSU(threshold + 1) for num in nums: for j in range(num, threshold + 1, num): dsu.union_set(num, j) unique_parents = set() for num in nums: if num > threshold: unique_parents.add(num) else: unique_parents.add(dsu.find(num)) return len(unique_parents)
-
type DSU struct { parent map[int]int rank map[int]int } func NewDSU(n int) *DSU { dsu := &DSU{ parent: make(map[int]int), rank: make(map[int]int), } for i := 0; i <= n; i++ { dsu.parent[i] = i dsu.rank[i] = 0 } return dsu } func (dsu *DSU) Find(x int) int { if dsu.parent[x] != x { dsu.parent[x] = dsu.Find(dsu.parent[x]) } return dsu.parent[x] } func (dsu *DSU) Union(u, v int) { uRoot := dsu.Find(u) vRoot := dsu.Find(v) if uRoot != vRoot { if dsu.rank[uRoot] < dsu.rank[vRoot] { uRoot, vRoot = vRoot, uRoot } dsu.parent[vRoot] = uRoot if dsu.rank[uRoot] == dsu.rank[vRoot] { dsu.rank[uRoot]++ } } } func countComponents(nums []int, threshold int) int { dsu := NewDSU(threshold) for _, num := range nums { for j := num; j <= threshold; j += num { dsu.Union(num, j) } } uniqueParents := make(map[int]struct{}) for _, num := range nums { if num > threshold { uniqueParents[num] = struct{}{} } else { uniqueParents[dsu.Find(num)] = struct{}{} } } return len(uniqueParents) }