Find earliest time all riders become connected
Company: Uber
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates graph connectivity and dynamic event-processing skills, testing conceptual understanding of connectivity in undirected graphs as well as practical algorithmic implementation for tracking when components merge; it belongs to the Coding & Algorithms category.
Part 1: Earliest Timestamp When All Riders Become Connected
Constraints
- 1 <= n <= 10^5
- 0 <= len(logs) <= 2 * 10^5
- Each log is [timestamp, a, b] with 0 <= a, b < n and a != b
- Timestamps are integers and logs may be unsorted
- An efficient near-linear solution after sorting is expected
Examples
Input: (6, [[20190104, 3, 4], [20190101, 0, 1], [20190107, 2, 3], [20190211, 1, 5], [20190224, 2, 4], [20190301, 0, 3], [20190312, 1, 2], [20190322, 4, 5]])
Expected Output: 20190301
Explanation: After sorting by time, the last merge needed to connect the two remaining groups happens at timestamp 20190301.
Input: (4, [[3, 0, 1], [1, 2, 3]])
Expected Output: -1
Explanation: The riders end up in two separate components: {0,1} and {2,3}.
Input: (1, [])
Expected Output: 0
Explanation: A single rider is trivially fully connected.
Input: (4, [[2, 0, 1], [2, 1, 2], [2, 2, 3]])
Expected Output: 2
Explanation: All riders become connected during timestamp 2.
Hints
- Sort the logs by timestamp so you process connections in chronological order.
- Use a Disjoint Set Union (Union-Find) structure and keep track of how many connected components remain.
Part 2: Earliest Valid Connectivity with BLOCK / UNBLOCK Events
Constraints
- 1 <= n <= 10^5
- 0 <= len(events) <= 2 * 10^5
- Each event is [timestamp, type, a, b] with type in {'RIDE', 'BLOCK', 'UNBLOCK'}
- 0 <= a, b < n and a != b
- Events may be unsorted, and multiple events may share the same timestamp
- An O(m log m) to O(m log^2 n) style solution is appropriate
Examples
Input: (3, [[1, 'RIDE', 0, 1], [2, 'BLOCK', 0, 2], [2, 'BLOCK', 1, 2]])
Expected Output: 2
Explanation: At time 2, riders 0 and 1 are connected, and both cross-component pairs involving rider 2 are blocked. Therefore every unblocked pair is connected.
Input: (4, [[1, 'BLOCK', 0, 2], [1, 'BLOCK', 0, 3], [1, 'BLOCK', 1, 2], [1, 'BLOCK', 1, 3], [2, 'RIDE', 0, 1], [3, 'RIDE', 2, 3]])
Expected Output: 3
Explanation: At time 3, the two ride-components are {0,1} and {2,3}. All four cross pairs between those components are blocked, so the condition holds.
Input: (3, [[1, 'BLOCK', 0, 2], [2, 'RIDE', 0, 1], [3, 'UNBLOCK', 0, 2], [4, 'RIDE', 1, 2]])
Expected Output: 4
Explanation: The unblock at time 3 breaks the condition. It becomes true again only when the whole ride graph becomes connected at time 4.
Input: (4, [[1, 'RIDE', 0, 1], [2, 'BLOCK', 0, 2]])
Expected Output: -1
Explanation: There are still many unblocked pairs across different ride-components, so the condition is never satisfied.
Input: (1, [])
Expected Output: 0
Explanation: A single rider satisfies the condition immediately.
Hints
- Think in terms of ride-connected components. The condition is true exactly when every pair of riders in different components is currently blocked.
- Maintain two counts: the total number of cross-component pairs, and how many active blocked pairs currently cross components. Union-Find helps with merges, and small-to-large map merging helps update blocked-pair counts efficiently.