Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Astronauts in the same connected component share a country. Count pairs from different countries = (total pairs) − (same-country pairs). Use Union-Find to get each component's size sᵢ, then answer = C(N,2) − Σ C(sᵢ,2). Equivalently, accumulate cross pairs as you go: for each size s, answer += s × (astronauts seen so far). O(N + E).
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you reframe 'pairs from different countries' as total minus same-country pairs, compute component sizes with Union-Find, and guard against 32-bit overflow.
Where candidates slip
Counting same-country pairs as the answer instead of its complement, forgetting isolated astronauts as size-1 components, or overflowing int on C(N,2).
How to stand out
Use complementary counting, present the running-sum accumulation that sidesteps the big C(N,2) intermediate, and state the long-vs-int overflow concern unprompted.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachExplore the full treeCollapse the tree
How to read it:Components {0,1,4} and {2,3}. Valid pairs cross the boundary between them.
How to read it:Subtract the easy-to-count same-country pairs from all pairs.
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
DFS / BFS Component Sizes + Complement (Baseline)
1Hint 1Explore hintHide hint
What single fact about each country do you actually need to count pairs? Not who is in it — just how many.
2Hint 2Explore hintHide hint
Build an adjacency list from the pairs and flood-fill each unvisited astronaut to measure its component size.
3Hint 3Explore hintHide hint
Total pairs are C(N,2). Pairs inside a country of size s are C(s,2). Subtract the sum of those from the total.
A · Core idea
The problem only depends on country sizes, so the graph work is reduced to component sizing — then it is pure combinatorics.
Why complementary counting. Counting cross-country pairs directly means, for each astronaut, adding up everyone in every other country — awkward and easy to double-count. The complement is trivial: the only forbidden pairs are within a single country, and a country of size s contributes exactly C(s,2) = s(s−1)/2 such pairs. So the answer is C(N,2) − Σ C(sᵢ,2).
Why flood fill gives the sizes. From any unvisited astronaut, walk the whole component, counting nodes. Each astronaut is visited exactly once, so the sizes partition all N astronauts — including singletons, which are countries of one and still pair with everyone outside.
Why the traversal must be iterative. With N up to 10⁵, a long chain of same-country relations can be 10⁵ deep. A recursive DFS would nest that many frames and overflow the call stack, so use an explicit stack (or a BFS queue). The visiting order is irrelevant to the sizes.
Why long, not int. C(N,2) for N = 10⁵ is about 5 × 10⁹, which silently wraps in a 32-bit int. Keep the total and all products in long.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
N = 5, pairs = [[0,1],[2,3],[0,4]]Interactive diagram
Flood fill sizing one country
flood from 0Starting at astronaut 0, the walk reaches 1 and 4 — size 3.
6C · Code with teaching comments
Reference implementation previewpublic long journeyToMoon(int n, int[][] pairs) { List<List<Integer>> adj = new ArrayList<>(); for (int i = 0; i < n; i++) adj.add(new ArrayList<>()); for (int[] p : pairs) { adj.get(p[0]).add(p[1]);Explore the full codeHide the full code
D · Why it works and complexityO(N + E) timeO(N + E) spaceOpen the invariant and proofExplore the proofHide the proof
Reframing 'different country' as 'all pairs minus same country' converts a tangled direct count into one subtraction. The graph reduces to a list of sizes; everything else is arithmetic.
ComplexityO(N + E) time, O(N + E) space — Adjacency list and flood fill each touch every vertex and edge once → O(N + E). The per-component arithmetic and the final subtraction are O(number of components) ≤ O(N).
E · Edge cases and pitfalls3Recursive DFS on a long chain of countrymen — stack overflow at 10⁵ nodes.Explore edge casesHide edge cases
Pitfalls
- Recursive DFS on a long chain of countrymen — stack overflow at 10⁵ nodes.
- Computing C(N,2) in int — overflows around N ≈ 65000.
- Forgetting that isolated astronauts are size-1 components that still pair outward.
Approach 2 of 2 · Optimal
Union-Find Sizes + Running-Sum Accumulation (Optimal)
1Hint 1Explore hintHide hint
You never need the relations after grouping — only the size of each country. What near-constant-time structure tracks 'are these two in the same group' and the group sizes?
2Hint 2Explore hintHide hint
Union-Find with path compression and union by rank. After unioning all pairs, each root carries its component size.
3Hint 3Explore hintHide hint
Walk the component sizes once. Keep a running 'astronauts seen so far'. Each new country of size s adds s × seen valid pairs (it pairs with everyone already counted).
A · Core idea
Union-Find is the right structure when only connectivity matters — it groups astronauts without ever building paths.
Building the countries. Start every astronaut in its own set. For each pair [a, b], union them. After all pairs, two astronauts share a root exactly when a chain of same-country relations links them — the transitivity of the relation falls out of the merging for free. The size[] array on each root gives each country's headcount.
Path compression and union by rank. A naïve find can walk an O(N) chain; compressing the path during find and attaching the shorter tree under the taller one pin each operation at O(α(N)) — at most about 4 for any realistic input. The find loop is a while, never recursive, so deep groups cannot overflow the stack.
The running-sum trick. Instead of computing C(N,2) and subtracting, count cross pairs directly as you sweep the component sizes. Keep seen = astronauts processed so far. When you reach a country of size s, every astronaut in it pairs with every one of the seen astronauts already counted (all in other countries), adding s × seen valid pairs. Then do seen += s. After the sweep, seen == N and the accumulated total is the answer. This never forms the large C(N,2) value, which keeps intermediate magnitudes smaller and the logic harder to get wrong.
Why this equals the complement formula. Summing s × seen over countries counts each cross-country pair exactly once — the later country contributes the pair against every earlier astronaut. That is algebraically identical to C(N,2) − Σ C(sᵢ,2); the running form is just a tidier way to evaluate it. Either way, use long.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
N = 5, pairs = [[0,1],[2,3],[0,4]]Interactive diagram
Disjoint-set forest after unions
union 0-1, 2-3, 0-4Two countries: {0,1,4} rooted at 0 (size 3) and {2,3} rooted at 2 (size 2).
6C · Code with teaching comments
D · Why it works and complexityO(N + E·α(N)) timeO(N) spaceOpen the invariant and proofExplore the proofHide the proof
Two ideas combine: Union-Find reduces the graph to a list of sizes in near-linear time, and the running-sum s × seen accumulation counts cross pairs without ever materializing the quadratic total. The second is a reusable counting pattern whenever you tally pairs across disjoint groups.
ComplexityO(N + E·α(N)) time, O(N) space — Each union/find is O(α(N)), effectively constant, so processing E pairs is O(E·α(N)). Reading sizes is O(N·α(N)). The running-sum sweep is O(number of components). Space is O(N) for parent and size arrays.
E · Edge cases and pitfalls7N = 1, pairs = [] — One astronaut, no possible pair → C(1,2) = 0. answer = 0.Explore edge casesHide edge cases
Edge cases handled
N = 1, pairs = []One astronaut, no possible pair → C(1,2) = 0. answer = 0.all astronauts same countryOne component of size N. seen stays 0 through the single country → answer 0; no cross pairs exist.no pairs at allN singleton countries → answer = C(N,2); every pair is cross-country.
Pitfalls
- Returning same-country pairs instead of their complement.
- Accumulating in int — answer up to 5 × 10⁹ overflows; use long.
- Counting size off non-root nodes — only the root holds the true component size.
- Recursive find on a deep group — risks stack overflow; use the iterative loop.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic long journeyToMoon(int n, int[][] pairs) { int[] parent = new int[n]; int[] rank = new int[n]; int[] size = new int[n]; for (int i = 0; i < n; i++) {Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Returning same-country pairs
The question asks for pairs from DIFFERENT countries. Summing C(sᵢ,2) gives the forbidden same-country pairs — the exact opposite of the answer.
Explore the code comparisonHide the code comparison
Returning same-country pairs
The question asks for pairs from DIFFERENT countries. Summing C(sᵢ,2) gives the forbidden same-country pairs — the exact opposite of the answer.
Don't write this
return sum(s * (s - 1) // 2 for s in sizes) # same-country pairsWrite this instead
total = n * (n - 1) // 2
return total - sum(s * (s - 1) // 2 for s in sizes)232-bit overflow on C(N,2)
For N = 10⁵, n*(n-1)/2 ≈ 5 × 10⁹, far beyond int's 2.1 × 10⁹ ceiling. The product n*(n-1) overflows before the division.
Explore the code comparisonHide the code comparison
32-bit overflow on C(N,2)
For N = 10⁵, n*(n-1)/2 ≈ 5 × 10⁹, far beyond int's 2.1 × 10⁹ ceiling. The product n*(n-1) overflows before the division.
Don't write this
int total = n * (n - 1) / 2; // n*(n-1) overflows intWrite this instead
long total = (long) n * (n - 1) / 2; // promote before multiplying3Missing isolated astronauts
An astronaut never named in any pair forms a country of one and pairs with everyone else. Only iterating over astronauts that appear in pairs drops these singletons and undercounts.
Explore the code comparisonHide the code comparison
Missing isolated astronauts
An astronaut never named in any pair forms a country of one and pairs with everyone else. Only iterating over astronauts that appear in pairs drops these singletons and undercounts.
Don't write this
for a, b in pairs: # only touches astronauts that appear in a pair
union(a, b)
sizes = component_sizes_of_seen_nodes()Write this instead
parent = list(range(n)) # every astronaut 0..n-1 starts as its own country
for a, b in pairs:
union(a, b)
# sweep all n astronauts, including untouched singletonsRevise
Carry the pattern into the interview
Pattern to remember
Component sizes via Union-Find, then complementary counting
Code pattern to memorize
sizes = component sizes from union-find
# complementary form
answer = N*(N-1)/2 - sum(s*(s-1)/2 for s in sizes)
# running-sum form (no big intermediate)
seen = 0; answer = 0
for s in sizes:
answer += s * seen
seen += sRules to remember
- 1Two astronauts in the same component are the same country — never a valid pair. Count its complement.
- 2Use
long: withNup to 10⁵,C(N,2)is about5 × 10⁹, well past 32-bit range. - 3Every astronaut counts, including isolated ones — they are singleton components of size 1.
- 4The running-sum form
answer += s × seenavoids forming the hugeC(N,2)and is overflow-friendlier. - 5Pick Union-Find for connectivity-only counting; you never need paths, just group sizes.
Use this pattern when
- Count cross-group pairs when items split into disjoint groups
- Connectivity defines the groups (a relation that is symmetric and transitive)
- You need group **sizes**, not paths or distances
- Complementary counting (total − unwanted) is simpler than counting wanted directly
Choose another pattern when
- You need the actual partner pairs, not the count → enumerate, but that is O(N²)
- Groups overlap or an item belongs to many → not disjoint sets
- You need shortest distance between astronauts → BFS, not component sizing
- Pairs must satisfy extra constraints beyond 'different country' → counting gets case-specific
Interview takeaway
When direct counting is messy, count the complement. Same-country pairs are easy (sum of C(sᵢ,2) over components), so subtract them from all pairs. Union-Find delivers the sizes in near-linear time.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternComponent Sizes + Complementary Pair Counting. Recognize it when you must count pairs across disjoint groups: compute group sizes with Union-Find, then either subtract Σ C(sᵢ,2) from C(N,2) or accumulate s × seen. The same size-then-combinatorics shape appears in Roads and Libraries and Components in a Graph.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Number of Connected ComponentsThe same Union-Find grouping, returning the component count instead of a pair tally.
- Components in a GraphReport smallest and largest component sizes — another read off the same size array.
- Roads and LibrariesPer-component greedy cost instead of a pair count, again powered by component sizes.
- Count of Pairs With Given PropertyComing soonGeneralized cross-group pair counting with the running-sum s × seen accumulation.