class UnionFind { parent: number[]; constructor(size: number) { this.parent = Array(size).fill(-1); } find(x: number): number { if (this.parent[x] < 0) return x; this.parent[x] = this.find(this.parent[x]); return this.parent[x]; } union(a: number, b: number): void { let rootA = this.find(a); let rootB = this.find(b); if (rootA !== rootB) { if (this.parent[rootA] <= this.parent[rootB]) { this.parent[rootA] += this.parent[rootB]; this.parent[rootB] = rootA; } else { this.parent[rootB] += this.parent[rootA]; this.parent[rootA] = rootB; } } } } const uf = new UnionFind(5); uf.union(0, 1); uf.union(1, 2); uf.union(3, 4); console.log(uf.parent);
The union operations merge sets by size. After union(0,1) and union(1,2), the root 0 has size -3 and nodes 1 and 2 point to 0. After union(3,4), root 3 has size -2 and node 4 points to 3.
const uf = new UnionFind(6); uf.union(0, 1); uf.union(2, 3); uf.union(4, 5); uf.union(1, 2);
Unions merge sets: (0,1) and (2,3) and (4,5) initially create 3 sets. Then union(1,2) merges sets containing 0,1 and 2,3 into one. So total sets become 2.
class UnionFind { parent: number[]; constructor(size: number) { this.parent = Array(size).fill(-1); } find(x: number): number { if (this.parent[x] < 0) return x; return this.find(this.parent[x]); } union(a: number, b: number): void { let rootA = this.find(a); let rootB = this.find(b); if (rootA !== rootB) { if (this.parent[rootA] < this.parent[rootB]) { this.parent[rootA] += this.parent[rootB]; this.parent[rootB] = rootA; } else { this.parent[rootB] += this.parent[rootA]; this.parent[rootA] = rootB; } } } } const uf = new UnionFind(2); uf.union(0, 1);
The find method lacks path compression assignment, so repeated calls cause infinite recursion when parent points to non-root.
class UnionFind { parent: number[]; constructor(size: number) { this.parent = Array(size).fill(-1); } find(x: number): number { if (this.parent[x] < 0) return x; this.parent[x] = this.find(this.parent[x]); return this.parent[x]; } union(a: number, b: number): void { let rootA = this.find(a); let rootB = this.find(b); if (rootA !== rootB) { if (this.parent[rootA] <= this.parent[rootB]) { this.parent[rootA] += this.parent[rootB]; this.parent[rootB] = rootA; } else { this.parent[rootB] += this.parent[rootA]; this.parent[rootA] = rootB; } } } } const uf = new UnionFind(4); uf.union(0, 1); uf.union(2, 3); console.log(uf.find(1)); console.log(uf.find(3)); console.log(uf.parent);
After unions, roots are 0 for set {0,1} and 2 for set {2,3}. find(1) returns 0 and updates parent[1] to 0. find(3) returns 2 and updates parent[3] to 2. Parent array reflects sizes and parents.
Union by size attaches smaller trees under larger ones to keep trees shallow, which speeds up find operations by reducing path length.