InterviewPrepKit

Home / Coding / Trees

Binary Search Tree Iterator

medium Original ↗
Solving tips
  • An iterator over a recursive structure is a paused traversal: turn iterative in-order traversal's call stack into explicit instance state you resume on each next().
  • Keep a stack holding the current node's left spine; the top is always the smallest unvisited value, and hasNext() is just 'stack non-empty'.
  • On next(), pop a node then push its right child's entire left spine (not just the right child), or values come out of order.
  • This meets the follow-up: amortized O(1) per call (each node pushed and popped once) and O(h) memory; say 'amortized' since one call can descend O(h).

Problem

Design an iterator that walks a binary search tree in in-order (ascending) order. Implement the class BSTIterator:

  • BSTIterator(root) — initialize with the root of the BST. The iterator starts positioned before the smallest element.
  • next() -> int — advance to the next element and return its value.
  • hasNext() -> bool — return whether an element remains to the right of the cursor.

All calls to next() are guaranteed to be valid (an element exists).

Follow-up: make next() and hasNext() run in average O(1) time using only O(h) memory, where h is the height of the tree.

Examples

Example 1

Input:  ["BSTIterator", "next", "next", "hasNext", "next", "hasNext"]
        [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], []]
Output: [null, 3, 7, true, 9, true]

In-order of the tree is 3, 7, 9, 15, 20 — the iterator yields it one value at a time; hasNext is true while values remain.

Example 2

Tree: [2,1,3]; calls: next(), next(), next(), hasNext()
Output: 1, 2, 3, false

After the last element is consumed, hasNext() turns false.

Constraints

  • The number of nodes is in the range [1, 10^5].
  • 0 <= Node.val <= 10^6
  • Up to 10^5 total calls to next and hasNext.

The O(h)-memory follow-up is what makes this Medium: flattening the whole tree up front is O(n) memory.

Think about it first

Hint 1 The easy version: what traversal produces a BST's values in sorted order, and what could you precompute in the constructor?
Hint 2 For O(h) memory, think about how *iterative* in-order traversal works with an explicit stack. What does the stack contain at any moment, and what does popping one node correspond to?
Hint 3 Keep a stack holding the path of "left-edge" nodes: pushing a node and all its left descendants costs amortized O(1) per `next`. Popping gives the next value; then push the popped node's right child's left spine. `hasNext` is just "stack non-empty".
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.