Solve Linked-List and Iterator Problems
Company: Airbnb
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates proficiency in linked-list pointer reasoning, cycle detection and shared-reference identification, as well as iterator design for round-robin merging, testing data-structure manipulation, iterator interfaces, and complexity analysis within the Coding & Algorithms domain.
Part 1: Determine Whether Two Possibly Cyclic Linked Lists Share Any Node
Constraints
- 0 <= len(next_index) <= 200000
- -1 <= head_a, head_b < len(next_index), unless len(next_index) is 0, in which case both heads must be -1
- For every i, next_index[i] is either -1 or an integer in the range [0, len(next_index) - 1]
- Each node has at most one outgoing edge, so each head defines a singly linked list that may contain a cycle
Examples
Input: ([1, 2, 3, -1, 5, 6, 3], 0, 4)
Expected Output: True
Explanation: List A is 0->1->2->3. List B is 4->5->6->3. They meet at node 3.
Input: ([1, 2, 0, 4, 5, 3], 0, 3)
Expected Output: False
Explanation: The lists are two separate cycles: 0->1->2->0 and 3->4->5->3.
Hints
- If you record every distinct node reachable from one head, the second traversal becomes a membership check.
- Because cycles are possible, stop traversing a list when you revisit a node.
Part 2: Return a Shared Node in Two Possibly Cyclic Linked Lists
Constraints
- 0 <= len(next_index) <= 200000
- -1 <= head_a, head_b < len(next_index), unless len(next_index) is 0, in which case both heads must be -1
- For every i, next_index[i] is either -1 or an integer in the range [0, len(next_index) - 1]
- Each node has at most one outgoing edge, so each head defines a singly linked list that may contain a cycle
Examples
Input: ([1, 2, 3, -1, 5, 6, 3], 0, 4)
Expected Output: 3
Explanation: The two lists first meet at node 3.
Input: ([1, 2, 0, 4, 5, 3], 0, 3)
Expected Output: -1
Explanation: The two cycles are completely separate.
Hints
- Store all distinct nodes reachable from the first head, then walk the second list until you either hit one of them or stop.
- To avoid infinite loops in cyclic lists, remember which nodes you have already visited during each traversal.
Part 3: Simulate a Round-Robin Multi-Stream Iterator
Constraints
- 0 <= len(streams) <= 100000
- 0 <= sum(len(stream) for stream in streams) <= 200000
- 0 <= len(operations) <= 200000
- Each stream element is a single-character string
- Every operation is either 'has_next' or 'next'
Examples
Input: ([['A', 'B', 'C'], ['x', 'y'], ['1', '2', '3', '4']], ['has_next', 'next', 'next', 'next', 'next', 'next', 'next', 'next', 'next', 'next', 'has_next'])
Expected Output: ['true', 'A', 'x', '1', 'B', 'y', '2', 'C', '3', '4', 'false']
Explanation: The iterator alternates among non-empty streams and skips exhausted ones.
Input: ([], ['has_next', 'next'])
Expected Output: ['false', 'EXCEPTION']
Explanation: With no streams, nothing can be read.
Hints
- Keep a queue of the stream indices that still have remaining characters.
- Store the current read position for each stream so that 'has_next' can stay O(1) and never consumes data.