Largest Component Size by Common Factor

Largest Component Size by Common Factor

Given a non-empty array of unique positive integers A, consider this graph:

There are A.length nodes, labeled A[0] to A[A.length - 1].

An edge exists between A[i] and A[j] if and only if A[i] and A[j] share a common factor greater than 1.

Return the size of the largest connected component in the graph.

Note:

  1. 1 <= A.length <= 20000
  2. 1 <= A[i] <= 100000

Solution: Union-Find + Brute Force

#define MAX_N 121000

class Solution {
public:
    int largestComponentSize(vector<int>& A) {
        // First 100000 positions hold all common factors of A[i]
        // Last 20000 positions handle up to 20000 elements
        for(int i=0;i<MAX_N;++i)
            parent[i]=i;
        fill(count, count+MAX_N, 0);
        
        for(int i=0;i<A.size();++i) {
            count[100001+i]=1;
            // Connect factors
            for(int j=2;j*j<=A[i];++j) {
                if (A[i]%j==0) {
                    unite(j, 100001+i);
                    unite(A[i]/j, 100001+i);
                }
            }
            // Connect all factors with input numbers
            unite(A[i], 100001+i);
        }
        
        // Return group with most nodes
        int res=1;
        for(int i=0;i<A.size();++i)
            res = max(res, count[find(100001+i)]);
        return res;
    }
    
    // Union-find structure
    void unite(int a, int b) {
        int i=find(a);
        int j=find(b);
        if (i==j) return;
        count[i]+=count[j];
        parent[j]=i;
    }
    
    int find(int a) {
        if (parent[a]==a) return a;
        return parent[a] = find(parent[a]);
    }
    
    int parent[MAX_N];
    int count[MAX_N];
};

You can use path compression to make lookups faster:

void unite(int a, int b) {
    int i=find(a);
    int j=find(b);
    if (i==j) return;
    if (rank[i]<rank[j]) {
        parent[i]=j;
        count[j]+=count[i];
    } else {
        parent[j]=i;
        count[i]+=count[j];
        if (rank[i]==rank[j]) ++rank[i];
    }
}

int find(int a) {
    if (parent[a]==a) return a;
    return parent[a] = find(parent[a]);
}

int parent[MAX_N];
int count[MAX_N];
int rank[MAX_N];

#union-find