C# DisjointSet/UnionFind (DSU) + bonus - DisjointSet implementation
Approach\n- Sort the inputs (queries and edgeList) by edge length (weight)\n- Use a two pointer approach to union all the nodes whose edges have length  (weight
# Approach\n- Sort the inputs (`queries` and `edgeList`) by edge length (weight)\n- Use a two pointer approach to union all the nodes whose edges have length  (weight) less than $$query[i]$$\n- If there is a path between them than their parents (in DSU) are the same\n\n# Bonus\n`DisjointSet` implementation which is reusable for other problems.\n\n# Complexity\n- Time complexity: $$O(M \\times log(M) + N \\times log(N))$$ , where $$M$$ is the number of edges in `edgeList` and $$N$$ - the number of queries\n- Space complexity: $$O(n)$$\n\n# Code\n```\npublic class Solution\n{\n    public class DisjointSet\n    {\n        private readonly int[] _parent;\n        private readonly int[] _rank;\n\n        public DisjointSet(int n)\n        {\n            _parent = new int[n];\n            _rank = new int[n];\n            for (var i = 0; i < n; i++)\n            {\n                _parent[i] = i;\n            }\n        }\n\n        public int Find(int x)\n        {\n            // If `x` is the parent of itself then `x` is the representative of this set\n            // Else we recursively call Find on its parent\n            var xSet = _parent[x] == x ? x : Find(_parent[x]);\n\n            // We cache the result by moving i\u2019s node directly under the representative of this set\n            _parent[x] = xSet;\n\n            return xSet;\n        }\n\n        public bool Union(int x, int y)\n        {\n            var xSet = Find(x);\n            var ySet = Find(y);\n\n            if (xSet == ySet)\n            {\n                // Elements are in same set, no need to unite anything.\n                return false;\n            }\n\n            if (_rank[xSet] < _rank[ySet])\n            {\n                // If x\u2019s rank is less than y\u2019s rank then move x under y\n                _parent[xSet] = ySet;\n            }\n            else if (_rank[xSet] > _rank[ySet])\n            {\n                // If y\u2019s rank is less than x\u2019s rank then move y under x\n                _parent[xSet] = ySet;\n            }\n            else\n            {\n                // If their ranks are the same\n                // Then move x under y (doesn\'t matter which one goes where)\n                _parent[xSet] = ySet;\n\n                // And increment the result tree\'s rank\n                _rank[xSet]++;\n            }\n\n            return true;\n        }\n    }\n\n    public bool[] DistanceLimitedPathsExist(int n, int[][] edgeList, int[][] queries)\n    {\n       var dsu = new DisjointSet(n);\n\n        // Add query indices to help with ordering results\n        for (var i = 0; i < queries.Length; i++)\n        {\n            queries[i] = new[] {queries[i][0], queries[i][1], queries[i][2], i};\n        }\n\n        Array.Sort(queries, (a, b) => a[2] - b[2]);\n        Array.Sort(edgeList, (a, b) => a[2] - b[2]);\n\n        var result = new bool[queries.Length];\n        var j = 0;\n\n        foreach (var query in queries)\n        {\n            // Two pointer => join the edges till their weight is less than the current query\n            for (; j < edgeList.Length && edgeList[j][2] < query[2]; ++j)\n            {\n                dsu.Union(edgeList[j][0], edgeList[j][1]);\n            }\n\n            // If parents are the same than their is a path\n            result[query[3]] = dsu.Find(query[0]) == dsu.Find(query[1]);\n        }\n\n        return result;\n    }\n}\n```
['C#']