Top K Users by Distinct Contacts
Reported by candidates from Google's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The Google OA reported in September 2026 looks like a simple top-k ranking, but the trap is in how you count. Repeated pairs, reversed pairs and self-messages all try to inflate a user's score, and a naive counter gets every one of them wrong. If you've got an invite and 48 hours, this is a hash-table-plus-heap problem with a few ugly edge cases. Build a set of contacts per user, rank by size, break ties lexically. Simple once you see it. If you blank mid-assessment, StealthCoder runs invisibly as a safety net and hands you the structure fast.
The problem
Each row of messages records one undirected message between two user IDs. Return at most k users ordered by descending number of distinct contacts, then by lexicographically smaller user ID. A repeated pair contributes one contact to each endpoint, regardless of direction. A self-message adds its user to the observed user set but adds no contact. If fewer than k users appear, return every observed user. Return an empty array when no user appears. Function topKActiveUsers(messages: String[][], k: int) → String[] Examples Example 1 messages = [["Ada","Bob"],["Ada","Cara"],["Bob","Cara"],["Ada","Drew"],["Bob","Ada"]] k = 2 return = ["Ada","Bob"] Ada has three contacts; Bob and Cara tie at two, so Bob wins the lexical tie. Example 2 messages = [["zoe","zoe"],["amy","bob"],["bob","amy"]] k = 5 return = ["amy","bob","zoe"] Repeated pairs count once, the self-message adds no contact, and fewer than k users are returned. Example 3 messages = [] k = 3 return = [] No users are present. Constraints 0 <= messages.length <= 200000. Every row contains exactly two nonempty case-sensitive user IDs. Each ID has at most 100 characters, and the combined input length is at most 2 * 10^6. 1 <= k <= 200000.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is deduplication before counting. Map each user ID to a hash set of contacts. For every row [a,b], add a to the observed set and b to the observed set. If a != b, add b to a's set and a to b's set. That handles repeated pairs, reversed direction and self-messages in one pass. Then rank users. A heap of size k works, but with n up to 200000 you can just sort observed users by (-setSize, id) and slice the first k. Sorting is O(u log u) and hard to get wrong. The common pitfall is a self-message creating a user with an empty set, or incrementing a counter instead of using a set. Another is forgetting that zoe still appears in the output. Compare IDs as case-sensitive strings. If the live OA rattles you, StealthCoder can surface this pattern while you keep your hands on the keyboard.
Memorize the pattern. If you can't, run StealthCoder. The proctor sees the IDE. They don't see what's behind it.
You can drill Top K Users by Distinct Contacts cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Google's OA.
Google reuses patterns across OAs. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Top K Users by Distinct Contacts FAQ
What's the trick in Top K Users by Distinct Contacts?+
Use a hash set of contacts per user, not a counter. Sets collapse repeated pairs and reversed pairs automatically. Register both users as observed on every row, but only add contacts when the two IDs differ. Then sort or heap by descending set size and ascending ID.
How hard is this Google OA question really?+
Medium-easy in algorithm, medium in care. There's no clever data structure beyond a map of sets and a sort. Most failures come from the self-message case, the fewer-than-k case, or the tiebreak direction. Test all three examples before submitting.
Should I use a heap or just sort?+
Either passes. Sorting all observed users by (-contacts, id) is shorter and less bug-prone. A min-heap of size k gives O(u log k) and matters only if you want to be tidy. Under OA pressure, sort and slice to k.
What edge cases break a naive solution?+
A self-message like [zoe,zoe] must add zoe to the output but give zero contacts. Duplicate and reversed pairs must count once. An empty messages array returns an empty array. And k larger than the user count returns everyone, so don't index past the list.
How do I prepare for this in 48 hours?+
Write the map-of-sets solution from scratch twice. Then practice custom comparators in your language for descending count and ascending string. Run the three given examples plus a case with mixed-case IDs, since the IDs are case-sensitive and uppercase sorts before lowercase.