Implement the BSTIterator class that represents an iterator over the in-order traversal of a binary search tree (BST):
BSTIterator(TreeNode root) Initializes an object of the BSTIterator class. The root of the BST is given as part of the constructor. The pointer should be initialized to a non-existent number smaller than any element in the BST.boolean hasNext() Returns true if there exists a number in the traversal to the right of the pointer, otherwise returns false.int next() Moves the pointer to the right, then returns the number at the pointer.Notice that by initializing the pointer to a non-existent smallest number, the first call to next() will return the smallest element in the BST.
You may assume that next() calls will always be valid. That is, there will be at least a next number in the in-order traversal when next() is called.
Example 1:
Input ["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"] [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []] Output [null, 3, 7, true, 9, true, 15, true, 20, false] Explanation BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]); bSTIterator.next(); // return 3 bSTIterator.next(); // return 7 bSTIterator.hasNext(); // return True bSTIterator.next(); // return 9 bSTIterator.hasNext(); // return True bSTIterator.next(); // return 15 bSTIterator.hasNext(); // return True bSTIterator.next(); // return 20 bSTIterator.hasNext(); // return False
Constraints:
[1, 105].0 <= Node.val <= 106105 calls will be made to hasNext, and next.
Follow up:
next() and hasNext() to run in average O(1) time and use O(h) memory, where h is the height of the tree?Problem Overview: Design an iterator for a Binary Search Tree that returns nodes in ascending order. The iterator exposes two operations: next() which returns the next smallest value and hasNext() which tells you if more nodes exist.
Approach 1: Using Stack for Controlled In-order Traversal (Time: O(1) average per operation, Space: O(h))
A BST's in-order traversal naturally produces values in sorted order. Instead of generating the entire traversal upfront, maintain a stack that simulates the recursion of in-order traversal. During initialization, push all nodes from the root down to the leftmost node. The top of the stack always represents the next smallest element.
When next() is called, pop the top node from the stack and return its value. If that node has a right child, push the right child and all of its left descendants onto the stack. This ensures the stack always holds the next valid traversal path. hasNext() simply checks whether the stack is empty.
This approach keeps only the traversal path in memory, not the entire tree. Each node is pushed and popped at most once, so the total traversal cost is O(n) across all calls, which makes each next() amortized O(1). Space usage is O(h), where h is the tree height. This method relies on a stack to simulate recursion and is the standard solution used in interviews.
Approach 2: Morris In-order Traversal (Time: O(1) average per operation, Space: O(1))
Morris traversal removes the need for an explicit stack by temporarily modifying the binary tree. The idea is to create a temporary "thread" from each node's in-order predecessor back to the current node. This allows the algorithm to return to a parent node after finishing its left subtree without recursion or a stack.
While iterating, if the current node has no left child, it is the next smallest element and the iterator moves to its right child. If a left child exists, find the rightmost node in that left subtree (the in-order predecessor). If the predecessor's right pointer is null, create a temporary link to the current node and move left. If the link already exists, remove it, output the current node, and move right.
Morris traversal visits each node at most twice and maintains O(1) extra space. The tradeoff is that the tree structure is temporarily modified during iteration, which can make the implementation more complex and less desirable in production iterators.
Recommended for interviews: The stack-based controlled in-order traversal is what interviewers typically expect. It clearly demonstrates understanding of BST ordering and iterative traversal using a stack. Mentioning Morris traversal shows deeper knowledge of tree traversal optimizations, but the stack approach is easier to reason about and aligns better with real iterator design.
This approach involves using a stack to simulate the in-order traversal of a binary search tree (BST). The stack is used to keep track of nodes to visit next, starting from the leftmost node (the smallest element). Each time next() is called, the stack pops one node, processes it, and then adds right child nodes to the stack to maintain the in-order sequence. This approach takes advantage of the tree's properties to efficiently traverse it.
The C solution for the BSTIterator uses a stack implemented as a linked list with basic stack operations like push and pop. The constructor initializes the stack with all left children of the root node. The `next` function pops the top of the stack, processes the node, and pushes any right child nodes' left children. The `hasNext` function checks if there are elements in the stack, indicating if another call to `next` is valid.
C++
Java
Python
C#
JavaScript
Time Complexity: The average time complexity is O(1) for next() and hasNext() methods, though next() can take up to O(h) time in the worst case, where h is the height of the tree.
Space Complexity: O(h) due to the depth of the stack, where h is the height of the tree.
Morris Traversal is an in-order tree traversal technique that doesn't require stack or recursion, thus using O(1) auxiliary space. It temporarily modifies the tree structure to maintain caching pointers, ensuring nodes are revisited as necessary. Once traversal completes, the tree reverts to its original form.
The C solution utilizes Morris traversal to achieve an in-order sequence without extra space. The iterator temporarily modifies the tree with connections called threads to track nodes. As the `next` method works through the tree, each accessed node prints its value and advances by fixing connections afterward. The `hasNext` method merely checks if the tree traversal has completed.
C++
Java
Python
C#
JavaScript
Time Complexity: O(1) on average, with O(n) total time for n nodes.
Space Complexity: O(1) without recourse to stack/recursion.
| Approach | Complexity |
|---|---|
| Approach 1: Using Stack for Controlled In-order Traversal | Time Complexity: The average time complexity is |
| Approach 2: Morris In-order Traversal | Time Complexity: |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Stack-based Controlled In-order Traversal | O(1) amortized per next(), O(n) total | O(h) | Best general solution for iterator design and interviews |
| Morris In-order Traversal | O(1) amortized per next(), O(n) total | O(1) | When minimizing extra memory is critical |
L50. Binary Search Tree Iterator | BST | O(H) Space • take U forward • 174,563 views views
Watch 9 more video solutions →Practice Binary Search Tree Iterator with our built-in code editor and test cases.
Practice on FleetCodePractice this problem
Open in Editor