Binary Search Tree Iterator - Complete Solution Guide
Binary Search Tree Iterator is LeetCode problem 173, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
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 poin
Detailed Explanation
The problem requires implementing an iterator for a Binary Search Tree (BST) that returns elements in in-order traversal sequence. The `BSTIterator` class needs to provide three methods: `BSTIterator(TreeNode root)` to initialize the iterator with the root of the BST, `next()` to return the next smallest element in the BST, and `hasNext()` to check if there are more elements available. The key constraint is to implement `next()` and `hasNext()` in average O(1) time and O(h) space, where 'h' is the height of the tree.
Solution Approach
The provided solution uses a stack to keep track of the nodes that need to be visited during the in-order traversal. The constructor initializes the stack by pushing the leftmost path of the BST onto the stack. The `next()` method pops a node from the stack (which is the next smallest element), and then pushes the leftmost path of the right subtree of that node onto the stack. The `hasNext()` method simply checks if the stack is empty. This approach amortizes the cost of traversing the tree to achieve O(1) average time complexity for both `next()` and `hasNext()` operations.
Step-by-Step Algorithm
- Step 1: **Initialization (Constructor):** Given the root, push the root and all of its left descendants onto the stack. This sets up the iterator to start at the smallest element.
- Step 2: **next() operation:** Pop the top element from the stack. This is the next smallest element in the BST.
- Step 3: If the popped node has a right child, push the right child and all of its left descendants onto the stack.
- Step 4: Return the value of the popped node.
- Step 5: **hasNext() operation:** Check if the stack is empty. If it's not empty, there are more elements to visit; otherwise, the traversal is complete.
Key Insights
- Insight 1: Using a stack to simulate the in-order traversal of the BST is crucial for achieving the desired time and space complexity.
- Insight 2: The `next()` operation must maintain the in-order traversal sequence by pushing the left path of the right subtree (if it exists) onto the stack.
- Insight 3: The stack will contain nodes that haven't been visited yet, maintaining the state of the traversal.
- Insight 4: Pre-calculating the entire in-order traversal and storing it in a list would violate the O(h) space requirement since it can be O(n) in the worst case
Complexity Analysis
Time Complexity: O(1)
Space Complexity: O(H)
Topics
This problem involves: Stack, Tree, Design, Binary Search Tree, Binary Tree, Iterator.
Companies
Asked at: LinkedIn, Media.net.