Skip to content

Commit fd4609e

Browse files
committed
Runtime: 320 ms (Top 50.0%) | Memory: 65.90 MB (Top 50.0%)
1 parent 54bd2f4 commit fd4609e

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Runtime: 320 ms (Top 50.0%) | Memory: 65.90 MB (Top 50.0%)
2+
3+
var magnificentSets = function(n, edges) {
4+
let uf = new UnionFind(n + 1);
5+
let graph = Array(n + 1).fill(0).map(() => []);
6+
for (let [a, b] of edges) { // 1. Build graph, connect nodes
7+
graph[a].push(b);
8+
graph[b].push(a);
9+
uf.union(a, b);
10+
}
11+
12+
let groups = {};
13+
for (let i = 1; i <= n; i++) { // 2. Find groups of connected nodes
14+
let parent = uf.find(i);
15+
if (!groups[parent]) groups[parent] = [];
16+
groups[parent].push(i);
17+
}
18+
19+
let totalGroups = 0;
20+
for (let parent in groups) { // 3. Find the maximum groups to divide for each connected group
21+
let group = groups[parent];
22+
let maxGroups = 0;
23+
for (let node of group) {
24+
let numGroups = bfs(graph, node);
25+
if (numGroups === -1) return -1;
26+
maxGroups = Math.max(maxGroups, numGroups);
27+
}
28+
totalGroups += maxGroups;
29+
}
30+
return totalGroups;
31+
};
32+
33+
function bfs(graph, startNode) {
34+
let queue = [startNode], n = graph.length;
35+
let levels = Array(n).fill(-1), level = 0;
36+
levels[startNode] = 0;
37+
while (queue.length) {
38+
for (let i = queue.length; i > 0; i--) {
39+
let node = queue.shift();
40+
for (let nei of graph[node]) {
41+
if (levels[nei] === -1) {
42+
levels[nei] = level + 1;
43+
queue.push(nei);
44+
} else if (levels[nei] === level) { // found an odd-lengthed cycle, we can't divide into groups
45+
return -1;
46+
}
47+
}
48+
}
49+
level++;
50+
}
51+
return level;
52+
}
53+
54+
class UnionFind {
55+
constructor(size) {
56+
this.root = Array(size);
57+
this.rank = Array(size)
58+
for (var i = 0; i < size; i++) {
59+
this.root[i] = i;
60+
this.rank[i] = 1;
61+
}
62+
}
63+
find(x) {
64+
if (this.root[x] === x) {
65+
return x;
66+
}
67+
return this.root[x] = this.find(this.root[x]);
68+
}
69+
union(x, y) {
70+
let rootX = this.find(x);
71+
let rootY = this.find(y);
72+
if (rootX !== rootY) {
73+
if (this.rank[rootX] > this.rank[rootY]) {
74+
this.root[rootY] = rootX;
75+
} else if (this.rank[rootX] < this.rank[rootY]) {
76+
this.root[rootX] = rootY;
77+
} else {
78+
this.root[rootY] = rootX;
79+
this.rank[rootX]++;
80+
}
81+
}
82+
}
83+
connected(x, y) {
84+
return this.find(x) === this.find(y);
85+
}
86+
}

0 commit comments

Comments
 (0)