function validTree(n, edges) {if (edges.length !== n - 1) return false;◄
const parent = [...Array(n).keys()];
const find = (x) => {while (parent[x] !== x) x = parent[x];
return x;
};
for (const [u, v] of edges) {const ru = find(u), rv = find(v);
if (ru === rv) return false; // cycle
parent[ru] = rv; // union
}
return true;
}
A tree on n nodes always has exactly n − 1 edges. Fewer and it can’t be connected; more and it must contain a cycle. So check the edge count first — it is a free early exit.
With the count right, the only remaining question is whether there is a cycle. Union–Find answers that: keep each node’s component, and join components as you add edges.
If an edge connects two nodes that are ALREADY in the same component, it closes a loop → not a tree.
If all n − 1 edges join two different components, no cycle ever formed — and n − 1 non-redundant merges must leave exactly one component, so it is automatically connected too.