C++: Union-Find with Rank, 97.19% time
c++\nclass Solution {\npublic:\n    // upper bound of N is 200\n    \n    // number of children\n    int children[210];\n    // index of parent\n    int par[210
```c++\nclass Solution {\npublic:\n    // upper bound of N is 200\n    \n    // number of children\n    int children[210];\n    // index of parent\n    int par[210];\n    \n    // find parent operation = amortized O(log n)\n    int findPar(int n){\n        if(par[n] == n) return n;\n        // move parent of every node along path to root\n        // this amortizes the whole findPar operation to O(log n).\n        // amortization is ONLY feasible if we unite by num of children\n        return par[n] = findPar(par[n]);\n    }\n    \n    //set union, considering rank\n    void unite(int a, int b){\n        // unite sets only if they are in different set.\n        if(findPar(a) == findPar(b)) return;\n        // make the smaller set be a subtree of the larger set.\n        // this preserves the amortization, otherwise findPar\n        // would run in worst-case O(N).\n        if(children[findPar(a)] > children[findPar(b)]){\n            children[findPar(a)] += children[findPar(b)];\n            par[findPar(b)] = findPar(a);\n        } else {\n            children[findPar(b)] += children[findPar(a)];\n            par[findPar(a)] = findPar(b);\n        }\n    }\n    \n    int findCircleNum(vector<vector<int>>& M) {\n        // get N\n        int n = M[0].size();\n        \n        for(int i = 0; i < n; ++i){\n            //initialize each node to be in its own tree\n            children[i] = 1;\n            par[i] = i;\n        }\n        for(int i = 0; i < n; ++i){\n            //ignore anything below and on diagonal\n            for(int j = i+1; j < n; ++j){\n                // unite if they are friends.\n                if(M[i][j] == 1) unite(i,j);\n            }\n        }\n        // the number of groups are the number of sets\n        // equals the number of root nodes\n        // equals the number of i where findPar(i) = i.\n        int count = 0;\n        for(int i = 0; i < n; ++i) if(findPar(i) == i) ++count;\n        return count;\n        \n        // Total Complexity: (amortized) O(N log N)\n        // 16 ms, faster than 97.19%\n        // Memory usage: 10.8mb\n    }\n};\n```\nhttps://leetcode.com/submissions/detail/280751633/\nIn my opinion, this algorithm is very useful and powerful. Look at how short and pretty the code is!\nTake the time to understand it - It\'s not a very complicated algorithm.\n\nGeeksForGeeks is a great resource to learn about this algo.\nhttps://www.geeksforgeeks.org/union-find/\nBest of luck :)
['Union Find', 'C']