leetcodealgorithms-templates3-tries
 
class UnionFind {
 
    constructor(n) {
        this.par = new Map();
        this.rank = new Map();
 
        for (let i = 1; i < n + 1; i++) {
            this.par.set(i,i);
            this.rank.set(i,0);
        }
    }
 
    // Find parent of n, with path compression.
    find(n) {
        let p = this.par.get(n);
        while (p != this.par.get(p)) {
            this.par.set(p, this.par.get(this.par.get(p)));
            p = this.par.get(p);
        }
        return p;
    }
 
    // Union by height / rank.
    // Return false if already connected, true otherwise.
    union(n1, n2) {
        let p1 = this.find(n1), p2 = this.find(n2);
        if (p1 == p2) {
            return false;
        }
 
        if (this.rank.get(p1) > this.rank.get(p2)) {
            this.par.set(p2, p1);
        } else if (this.rank.get(p1) < this.rank.get(p2)) {
            this.par.set(p1, p2);
        } else {
            this.par.set(p1, p2);
            this.rank.set(p2, this.rank.get(p2) + 1);
        }
        return true;
    }
}