Implement a lazy inorder traversal iterator
Company: Apple
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of binary tree traversal and iterator design, specifically the implementation of a lazy inorder iterator under target space and amortized time constraints; it belongs to the Coding & Algorithms category and emphasizes practical implementation skills.
Constraints
- 0 <= len(tree_values) <= 100000
- Each non-None tree value is an integer in the range [-10^9, 10^9]
- 0 <= len(operations) <= 200000
- Every `next` operation is valid: it is never called when the iterator is exhausted
- Do not precompute the full inorder traversal; target auxiliary iterator space is O(h)
Examples
Input: ([4, 2, 6, 1, 3, 5, 7], ['hasNext', 'next', 'hasNext', 'next', 'next', 'next', 'next', 'next', 'next', 'hasNext'])
Expected Output: [True, 1, True, 2, 3, 4, 5, 6, 7, False]
Explanation: The inorder traversal of the tree is [1, 2, 3, 4, 5, 6, 7]. `hasNext` does not consume elements.
Input: ([], ['hasNext', 'hasNext'])
Expected Output: [False, False]
Explanation: An empty tree has no inorder values, so `hasNext` is always False.
Input: ([1, None, 2, 3], ['next', 'next', 'next', 'hasNext'])
Expected Output: [1, 3, 2, False]
Explanation: The tree has root 1, right child 2, and 2 has left child 3. Its inorder traversal is [1, 3, 2].
Input: ([5, 3, 7, 3, 4, None, 7], ['next', 'next', 'next', 'next', 'next', 'next'])
Expected Output: [3, 3, 4, 5, 7, 7]
Explanation: This verifies correct lazy traversal when duplicate values appear in the tree.
Hints
- Store only the path of nodes that could produce the next inorder value. A stack is useful here.
- After returning a node, the next inorder value comes from the leftmost path of its right subtree.