C++ || Simple and Easy Explanation || Union-Find
IntuitionApproachComplexity
Time complexity:

Space complexity:
Code
# Intuition
<!-- Describe your first thoughts on how to solve this problem. --> 
    We need to find connected components,
    The most intitutive approach for that is Union Set.

# Approach
<!-- Describe your approach to solving the problem. -->
    1.Write a function for intersect using two pointer.
        For that we need to sort the vectors in properties.
    2.Create class for unionSet.
    3.We use two for loops and compare all the vectors to find nodes,
        with edges.
    4.Check each node, if it is parent of itself, it is root node so
        increase count of component.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```cpp []
class Solution {
private:
    int intersect(vector<int>& a, vector<int>& b){
        /*this is brute force for understanding
        gives tle on last taste case
        int ans = 0;
        unordered_set<int> sta(a.begin(),a.end());
        unordered_set<int> stb(b.begin(),b.end());

        for(auto it:sta){
            if(stb.find(it) != stb.end()) ans++;
        }
        return ans;*/
        int ans = 0;
        int i = 0, j = 0;
        while (i < a.size() && j < b.size()) {
            if (a[i] == b[j]) {
                ans++;
                int val = a[i];
                // skip duplicates in both arrays
                while (i < a.size() && a[i] == val) i++;
                while (j < b.size() && b[j] == val) j++;
            } else if (a[i] < b[j]) {
                i++;
            } else {
                j++;
            }
        }
        return ans;
    }
    class unionFind{
    public:
        vector<int> parent,size;
        unionFind(int n) : parent(n,-1),size(n,1) {}

        int find(int node){
            if(parent[node] == -1){
                return node;
            }
            return parent[node] = find(parent[node]);
        }

        void unionSet(int a,int b){
            int pa = find(a);
            int pb = find(b);

            if(pa == pb) return;

            if(size[pa] > size[pb]){
                parent[pb] = pa;
                size[pa] += size[pb];
            }
            else{
                parent[pa] = pb;
                size[pb] += size[pa];
            }
        }
    };
public:
    int numberOfComponents(vector<vector<int>>& properties, int k) {
        int n = properties.size();
        for (auto& v : properties) {
            sort(v.begin(), v.end());
        }
        unionFind dsu(n);
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(intersect(properties[i],properties[j]) >= k){
                    dsu.unionSet(i,j);
                }
            }
        }

        int ans = 0;
        for(int i=0;i<n;i++){
            if(dsu.find(i) == i){
                ans++;
            }
        }
        return ans;
    }
};
```
['Two Pointers', 'Union Find', 'C++']