Simulate a Rank-Based Tournament
Company: Uber
Role: Frontend Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates ability to simulate tournament pairing and single-elimination progression using array manipulation and data structures while preserving original player identifiers, plus relational schema design and SQL querying for storing and retrieving match records.
Part 1: Simulate a Rank-Based Single-Elimination Tournament
Constraints
- 0 <= len(ranks) <= 200000
- 1 <= ranks[i] <= 10^9
- All rank values are distinct
- The original player IDs must be preserved in the output
Examples
Input: [3, 1, 4, 2]
Expected Output: [[[[0, 1, 1], [2, 3, 3]], [[1, 3, 1]]], 1]
Explanation: Round 1: player 1 beats 0, and player 3 beats 2. Final: player 1 beats player 3.
Input: [5, 2, 4]
Expected Output: [[[[0, 1, 1], [2, -1, 2]], [[1, 2, 1]]], 1]
Explanation: Player 2 gets a bye in round 1, then loses to player 1 in the final.
Input: [4, 1, 5, 3, 2]
Expected Output: [[[[0, 1, 1], [2, 3, 3], [4, -1, 4]], [[1, 3, 1], [4, -1, 4]], [[1, 4, 1]]], 1]
Explanation: This case shows multiple rounds with byes preserved in the output.
Input: []
Expected Output: [[], -1]
Explanation: No players means no rounds and no champion.
Input: [7]
Expected Output: [[], 0]
Explanation: A single player is already the champion, so there are no matches.
Hints
- Keep each active player as a pair of (player_id, rank) so you never lose the original ID.
- Build the next round while recording the current round. If one player is left over, record a bye as [player_id, -1, player_id].
Part 2: Emulate Relational Queries for Tournament Matches
Constraints
- 0 <= len(matches) <= 200000
- Each row in matches has exactly 8 integers
- match_id values are unique
- player IDs and tournament IDs are non-negative, except playerB may be -1 for a bye
- played_at is an integer timestamp and is not necessarily unique
Examples
Input: ([[101, 1, 1, 1, 10, 0, 1, 1], [102, 1, 1, 2, 20, 2, 3, 2], [103, 1, 2, 1, 30, 1, 2, 1], [201, 2, 1, 1, 15, 0, 4, 0]], 0, 1)
Expected Output: [[[101, 1, 1, 1, 10, 0, 1, 1], [201, 2, 1, 1, 15, 0, 4, 0]], [[101, 1, 1, 1, 10, 0, 1, 1], [102, 1, 1, 2, 20, 2, 3, 2], [103, 1, 2, 1, 30, 1, 2, 1]]]
Explanation: Player 0 appears in match 101 and 201. Tournament 1 contains matches 101, 102, and 103.
Input: ([[5, 3, 1, 1, 100, 7, 8, 7], [2, 3, 1, 2, 100, 9, 10, 10], [8, 3, 2, 1, 110, 7, 10, 7]], 10, 3)
Expected Output: [[[2, 3, 1, 2, 100, 9, 10, 10], [8, 3, 2, 1, 110, 7, 10, 7]], [[2, 3, 1, 2, 100, 9, 10, 10], [5, 3, 1, 1, 100, 7, 8, 7], [8, 3, 2, 1, 110, 7, 10, 7]]]
Explanation: Two tournament matches share the same timestamp, so the smaller match_id comes first.
Input: ([], 1, 99)
Expected Output: [[], []]
Explanation: With no rows, both query results are empty.
Input: ([[1, 1, 1, 1, 5, 3, -1, 3], [2, 1, 2, 1, 10, 3, 4, 3], [3, 2, 1, 1, 7, 8, 9, 8]], 4, 1)
Expected Output: [[[2, 1, 2, 1, 10, 3, 4, 3]], [[1, 1, 1, 1, 5, 3, -1, 3], [2, 1, 2, 1, 10, 3, 4, 3]]]
Explanation: The bye row is still a tournament match, but only the second row involves player 4.
Hints
- This is the in-memory version of SQL WHERE plus ORDER BY.
- Be careful with byes: playerB = -1 should not match any real player ID.