Last Updated: March 29, 2026
We have a binary search tree and need to find the kth smallest element in it. Since it's a BST, there's an implicit sorted order hiding in the tree structure. An in-order traversal (left, root, right) visits BST nodes in ascending order. So the kth node visited during an in-order traversal is our answer.
The real question is how efficiently we can get to that kth node. A naive approach would collect all values into a sorted list and pick the kth one. But we can do better by stopping the traversal as soon as we've visited k nodes, without needing to process the entire tree.
1 <= k <= n <= 10^4 → k is always valid (never larger than the number of nodes). We don't need to handle the case where k exceeds the tree size. With n up to 10,000, even O(n) approaches are fine.0 <= Node.val <= 10^4 → Non-negative integer values. No overflow concerns.The most straightforward approach exploits the fundamental property of a BST: an in-order traversal produces values in ascending order. If we collect all values into a list via in-order traversal, the kth smallest is simply the element at index k-1.
This is the approach most people think of first. It's correct and easy to implement, but it does more work than necessary because it traverses the entire tree even if k is 1.
k - 1 from the list.This works correctly but always traverses the entire tree and stores all values. What if we stopped the moment we found the kth element instead of collecting everything first?
We know in-order traversal visits BST nodes in ascending order. Instead of collecting all values and then picking the kth one, we can count as we traverse and stop the moment our count reaches k.
The idea is simple: maintain a counter that increments each time we "visit" a node (the middle step of in-order). When the counter hits k, we've found our answer. The trick in the recursive version is propagating this early termination. We use class-level variables (or pass state by reference) to track the count and result across recursive calls.
The BST property guarantees that an in-order traversal visits nodes in ascending order. By counting each visit, the kth node we visit is exactly the kth smallest. The early return stops unnecessary processing, but in the recursive version, the "return" only exits the current call frame. The parent calls still need to check whether the result was found before recursing into the right subtree.
The recursive early-stop works well, but the termination isn't perfectly clean since returning only exits the current call frame. What if we used an iterative approach with an explicit stack so we could return the answer immediately?
An iterative in-order traversal gives us the same ascending visit order as the recursive version, but with one significant advantage: we have full control over when to stop. The moment we've visited the kth node, we return immediately. No call stack to unwind, no extra recursive calls.
The iterative approach uses an explicit stack. We push nodes as we go left, then pop a node, "visit" it (decrement k), and if k reaches 0, that node's value is our answer. Otherwise, move to its right child and repeat the process.
The iterative approach simulates exactly what the call stack does during recursive in-order traversal. Each time we push nodes going left, we're mimicking the recursive descent into left subtrees. When we pop, we're at the "visit" step. Moving to the right child is the equivalent of the recursive call on the right subtree. The critical advantage is that when k reaches 0, we return instantly from the function. No stack unwinding, no wasted processing.