UnionFind beats 100%. Simple and intuitive explanation.
Intuition\n Describe your first thoughts on how to solve this problem. \nThis is just an extension of UnionFind alorithm (Disjoint set)\n# Approach\n Describe y
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\nThis is just an extension of UnionFind alorithm (Disjoint set)\n# Approach\n<!-- Describe your approach to solving the problem. -->\nLets consider we have a restriction A-C\nNow when we\'ve a request connecting D to C, there are 2 possibilities.\n            1. C will be the parent of D\n            2. D will be the parent of C\n\nCase 1: C will be the parent of D\n            The restrictions of D will be added to restrictions of C. For our case, D does not have any restrictions. \n\nCase 2: D will be the parent of C\n            In this case, the restrictions Set[C] will have A. The restrictions of C will be added to restrictions of D. That is, A is also added to D. Now when A is getting unionized to this component with A-D, we will check if we have any restrictions. Yes, D is the parent and it has restrictions on A. As restrictions of C were added to D.\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\nO(\u03B1(N)) \n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\nO(N)\n\n# Code\n```\n    class UnionFind {\n        int[] root;\n        int[] size;\n        Set<Integer>[] restrictions;\n\n        public UnionFind(int n) {\n            root = new int[n];\n            size = new int[n];\n            restrictions = new Set[n];\n\n            for (int i = 0; i < n; i++) {\n                root[i] = i;\n                size[i] = 1;\n                restrictions[i] = new HashSet<>();\n            }\n        }\n\n        public void addRestrictions(int[][] restricts) {\n            for (int[] r : restricts) {\n                restrictions[r[0]].add(r[1]);\n                restrictions[r[1]].add(r[0]);\n            }\n        }\n\n\n        public int find(int x) {\n            if (x == root[x]) return x;\n            return root[x] = find(root[x]);\n        }\n\n        public boolean union(int x, int y) {\n            int rootX = find(x);\n            int rootY = find(y);\n\n            if (rootX == rootY) return true;\n            if (restrictions[rootX].contains(rootY) || restrictions[rootY].contains(rootX)) return false;\n\n            // Lets consider we have a restriction A-C\n            // Now when we\'re connecting D to C, there are 2 possibilities.\n            //      1. C will be the parent of D\n            //      2. D will be the parent of C\n\n            // Case 1: C will be the parent of D\n            // The restrictions of D will be added to restrictions of C. For our case, D does not have any restrictions. \n\n            // Case 2: D will be the parent of C\n            // In this case, the restrictions Set[C] will have A. The restrictions of C will be added to restrictions of D. That is, A is also added to D. Now when A is getting unionized to this component with A-D, we will check in the line above if we have any restrictions. Yes, D is the parent and it has restrictions on A. As restrictions of C were added to D.\n            if (size[rootX] > size[rootY]) {\n                root[rootY] = rootX;\n                for (Integer r : restrictions[rootY]) {\n                    restrictions[rootX].add(find(r));\n                }\n            } else if (size[rootX] < size[rootY]) {\n                root[rootX] = rootY;\n                for (Integer r : restrictions[rootX]) {\n                    restrictions[rootY].add(find(r));\n                }\n            } else {\n                root[rootY] = rootX;\n                for (Integer r : restrictions[rootY]) {\n                    restrictions[rootX].add(find(r));\n                }\n                size[rootX]++;\n            }\n            return true;\n        }\n\n    }\n\nclass Solution {\n\n\n\n    public boolean[] friendRequests(int n, int[][] restrictions, int[][] requests) {\n        UnionFind uf = new UnionFind(n);\n        uf.addRestrictions(restrictions);\n        boolean[] result = new boolean[requests.length];\n\n        for (int i = 0; i < requests.length; i++) {\n            result[i] = uf.union(requests[i][0], requests[i][1]);\n        }\n        return result;\n\n    }\n\n    \n}\n```
['Java']