public class UnionFind
{
    private int[] parent;
    private int[] rank;

    public UnionFind(int size)
    {
        parent = new int[size];
        rank = new int[size];

        for (int i = 0; i < size; i++)
        {
            parent[i] = i;
        }
    }

    public void union(int p, int q)
    {
        int pParent = find(p);
        int qParent = find(q);

        if (pParent == qParent)
        {
            return;
        }

        if (rank[p] < rank[q])
        {
            parent[pParent] = qParent;
        }
        else
        {
            parent[qParent] = pParent;

            if (rank[p] == rank[q])
            {
                rank[p]++;
            }
        }
    }

    public int find(int p)
    {
        if (parent[p] != p)
        {
            int root = find(parent[p]);
            parent[p] = root;
        }

        return parent[p];
    }

    public int countTrees()
    {
        for (int i = 0; i < parent.length; i++)
        {
            // To compress path
            find(i);
        }

        HashSet<Integer> hs = new HashSet<Integer>();
        for (int i = 0; i < parent.length; i++)
        {
            hs.add(parent[i]);
        }

        return hs.size();
    }
}
@@ -67,16 +67,39 @@
 %5B%5D rank;
+%0A    private int count;
 %0A%0A    pu
@@ -190,16 +190,38 @@
 t%5Bsize%5D;
+%0A        count = size;
 %0A%0A      
@@ -730,32 +730,50 @@
      %7D%0A        %7D
+%0A%0A        count--;
 %0A    %7D%0A%0A    publ
@@ -995,305 +995,25 @@
     
-for (int i = 0; i %3C parent.length; i++)%0A        %7B%0A            // To compress path%0A            find(i);%0A        %7D%0A%0A        HashSet%3CInteger%3E hs = new HashSet%3CInteger%3E();%0A        for (int i = 0; i %3C parent.length; i++)%0A        %7B%0A            hs.add(parent%5Bi%5D);%0A        %7D%0A%0A        return hs.size()
+return count
 ;%0A    %7D%0A
 %7D
@@ -1011,9 +1011,10 @@
 ;%0A    %7D%0A
-
 %7D
+%0A

Improve way of counting trees in UnionFind