Python 0173.py
class BSTIterator:
def walk(self, node):
if node:
self.walk(node.left)
self.inorder.append(node.val)
self.walk(node.right)
def __init__(self, root: Optional[TreeNode]):
self.inorder = []
self.walk(root)
def next(self) -> int:
return self.inorder.pop(0)
def hasNext(self) -> bool:
return len(self.inorder) > 0
Difficulty
and has an acceptance rate of about 77% (1+ million submissions).
Typical patterns to solve this problem:
- Binary Search Tree
- Binary Tree
- Design
- Iterator
- Stack
- Tree
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation defines a binary search tree iterator that yields the node values in ascending order. The iterator builds a complete in-order traversal of the tree at construction time and then serves elements sequentially through the next method while exposing the availability of further elements via hasNext. The design isolates the traversal logic in a private helper method and stores the result in a list that acts as a queue for subsequent calls.
Construction Phase
During object creation the constructor receives the root of a binary search tree. It initializes an empty list named inorder and immediately triggers a depth-first walk of the tree.
def __init__(self, root: Optional[TreeNode]):
self.inorder = []
self.walk(root)
The walk method implements a classic recursive in-order traversal. For each non-null node it first recurses on the left child, appends the node’s value to the inorder list, and finally recurses on the right child.
def walk(self, node):
if node:
self.walk(node.left)
self.inorder.append(node.val)
self.walk(node.right)
Because the traversal is performed once, the iterator captures the entire sorted sequence up front, eliminating the need for further tree navigation during iteration.
Retrieval of the Next Element
The next method returns the smallest remaining value by removing the first element of the stored list.
def next(self) -> int:
return self.inorder.pop(0)
By using pop(0), the method delivers values in the order they were recorded during the initial traversal. The removal also shrinks the list, ensuring that subsequent calls progress through the sequence without additional indexing.
Availability Check
The hasNext method reports whether any elements remain to be produced. It inspects the length of the inorder list and returns a Boolean result.
def hasNext(self) -> bool:
return len(self.inorder) > 0
This check guards against attempts to retrieve values when the iterator has been exhausted, allowing client code to query the iterator safely before invoking next.
Edge Cases Handled
When the input tree is empty, the constructor receives a None root. The walk method immediately returns without modifying the inorder list, leaving it empty. Consequently, hasNext evaluates to False and next is never called, preventing errors.
A tree consisting of a single node triggers a single recursive call that appends that node’s value to the list. The iterator then yields exactly one element before hasNext becomes False.
Repeated calls to hasNext after the iterator is exhausted continue to return False because the list remains empty, demonstrating stable behavior under successive queries.
Performance Optimizations
The primary optimization is the eager construction of the full in-order sequence. By performing the traversal once during initialization, the iterator avoids repeated recursive calls or stack management during each next operation. This results in constant-time retrieval of the next element, as the method merely extracts the first list entry.
Storing the traversal in a Python list provides fast indexed access and efficient memory layout. The use of pop(0) removes the front element without requiring additional data structures such as explicit queues, leveraging the list’s built-in capabilities.
Overall, the design trades a one-time linear pass over the tree and the associated memory consumption for rapid, straightforward iteration thereafter.
ELI5 - Simplified Explanation
Imagine a tree made of numbers. Some numbers are on the left and some are on the right. This code acts like a little helper that visits every single number in that tree, but it does so in a very special order from smallest to biggest.
First, the helper starts at the very top of the tree. It looks to the left as far as it can go to find the smallest number. When it finds a number, it writes it down on a list. Then it goes to the next number and writes that one down too, until the whole list is filled up from smallest to largest.
Whenever someone asks for the next number, the helper takes the very first number from the top of the list and gives it away. It keeps doing this until the list is completely empty.
If someone wants to know if there are still more numbers left to see, the helper just checks if the list still has anything inside it. If the list has numbers, it says yes. If the list is empty, it says no.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | |||||||||||
| www | AlgoMonster | C++ | Python | Java | TS | |||||||
| WalkCCC | C++ | Python | Java | |||||||||
| leetcode.ca | C++ | Python | Java | JS | Rust | Go | TS | |||||
| LeetcodeHelp | C++ | Python | Java | |||||||||
| MemoryLimitExceeded | C++ | Python | ||||||||||
| Progiez | C++ | Python | Java | |||||||||
| github | aylei | Rust | ||||||||||
| begeekmyfriend | C | |||||||||||
| BigEggStudy | C# | |||||||||||
| black-shadows | C++ | |||||||||||
| charles-wangkai | Java | |||||||||||
| chenyanzhe | C++ | |||||||||||
| everthis | JS | |||||||||||
| fartem | Ruby | |||||||||||
| FelixFan1122 | C# | |||||||||||
| fengvyi | C++ | |||||||||||
| fpdjsns | C++ | |||||||||||
| gaosq0604 | Python | |||||||||||
| Garvit244 | Python | |||||||||||
| halfrost | Go | |||||||||||
| haoel | C++ | |||||||||||
| JoshCrozier | JS | |||||||||||
| keineahnung2345 | C++ | |||||||||||
| Krazune | C++ | |||||||||||
| lennylxx | C++ | |||||||||||
| linouk23 | C++ | |||||||||||
| lkwq007 | Python | |||||||||||
| luangong | C++ | |||||||||||
| MacJim | C++ | |||||||||||
| shreymehul | C# | |||||||||||
| suxrobGM | C# | |||||||||||
| varunu28 | Java | |||||||||||
| vli02 | C | |||||||||||
| vthwang | Java | |||||||||||
| wisdompeak | C++ | |||||||||||
| XiaotaoGuo | C++ | |||||||||||
| yuanliu666 | Kotlin | |||||||||||
| YuriSpiridonov | Python | |||||||||||
| zfang399 | C++ | |||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||||||
| WalkCCC | C++, Python, Java | |||||||||||
| leetcode.ca | C++, Go, Java, JavaScript, Python, Rust, TypeScript | |||||||||||
| LeetcodeHelp | C++, Java, Python | |||||||||||
| MemoryLimitExceeded | Python, C++ | |||||||||||
| Progiez | C++, Java, Python | |||||||||||
| aylei | Rust | |||||||||||
| begeekmyfriend | C | |||||||||||
| BigEggStudy | C# | |||||||||||
| black-shadows | C++, C++ | |||||||||||
| charles-wangkai | Java | |||||||||||
| chenyanzhe | C++ | |||||||||||
| everthis | JavaScript | |||||||||||
| fartem | Ruby | |||||||||||
| FelixFan1122 | C# | |||||||||||
| fengvyi | C++ | |||||||||||
| fpdjsns | C++ | |||||||||||
| gaosq0604 | Python | |||||||||||
| Garvit244 | Python | |||||||||||
| halfrost | Go | |||||||||||
| haoel | C++ | |||||||||||
| JoshCrozier | JavaScript | |||||||||||
| keineahnung2345 | C++ | |||||||||||
| Krazune | C++ | |||||||||||
| lennylxx | C++ | |||||||||||
| linouk23 | C++ | |||||||||||
| lkwq007 | Python | |||||||||||
| luangong | C++ | |||||||||||
| MacJim | C++ | |||||||||||
| shreymehul | C# | |||||||||||
| suxrobGM | C# | |||||||||||
| varunu28 | Java | |||||||||||
| vli02 | C | |||||||||||
| vthwang | Java | |||||||||||
| wisdompeak | C++ | |||||||||||
| XiaotaoGuo | C++ | |||||||||||
| yuanliu666 | Kotlin | |||||||||||
| YuriSpiridonov | Python | |||||||||||
| zfang399 | C++ |
Videos
Similar Problems
- problem 94: Binary Tree Inorder Traversal
- problem 251: Flatten 2D Vector
- problem 281: Zigzag Iterator
- problem 285: Inorder Successor in BST
- problem 426: Convert Binary Search Tree to Sorted Doubly Linked List
- problem 1586: Binary Search Tree Iterator II
Solved On The Same Day
- problem 144: Binary Tree Preorder Traversal
- problem 145: Binary Tree Postorder Traversal
- problem 222: Count Complete Tree Nodes
- problem 404: Sum of Left Leaves
- problem 501: Find Mode in Binary Search Tree
- problem 543: Diameter of Binary Tree
- problem 559: Maximum Depth of N-ary Tree
- problem 589: N-ary Tree Preorder Traversal
- problem 590: N-ary Tree Postorder Traversal
- problem 637: Average of Levels in Binary Tree
- problem 700: Search in a Binary Search Tree
- problem 703: Kth Largest Element in a Stream
- problem 79: Word Search
- problem 81: Search in Rotated Sorted Array II
- problem 97: Interleaving String
- problem 99: Recover Binary Search Tree
- problem 199: Binary Tree Right Side View
- problem 230: Kth Smallest Element in a BST
- problem 235: Lowest Common Ancestor of a Binary Search Tree
- problem 341: Flatten Nested List Iterator
- problem 429: N-ary Tree Level Order Traversal
- problem 508: Most Frequent Subtree Sum
- problem 513: Find Bottom Left Tree Value
- problem 538: Convert BST to Greater Tree
- problem 65: Valid Number
- problem 85: Maximal Rectangle
- problem 87: Scramble String
- problem 126: Word Ladder II
- problem 127: Word Ladder
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality