Problem
Given the root of a Binary Search Tree (BST) and an integer k, return the kth smallest element in the tree.
A BST has an important property:
- Every value in the left subtree is smaller than the current node.
- Every value in the right subtree is greater than the current node.
Example:
4
/ \
2 6
/ \ / \
1 3 5 7The values in sorted order are:
1, 2, 3, 4, 5, 6, 7If k = 4, the answer is 4.
The Key Observation
The biggest hint is that the tree is a Binary Search Tree, not just a binary tree.
If we traverse a BST using inorder traversal:
Left → Node → Right
we visit the nodes in ascending sorted order.
For the previous example:
4
/ \
2 6
/ \ / \
1 3 5 7The inorder traversal visits:
1 → 2 → 3 → 4 → 5 → 6 → 7That means:
- 1st smallest = first node visited
- 2nd smallest = second node visited
- kth smallest = kth node visited
This completely avoids sorting anything.
Approach 1 — Recursive Inorder DFS
Your recursive solution performs an inorder traversal while counting how many nodes have been visited.
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
self.index = 0
self.res = 0
def dfs(node):
if not node:
return
dfs(node.left)
self.index += 1
if self.index == k:
self.res = node.val
return
dfs(node.right)
dfs(root)
return self.resHow it works
Imagine this BST:
5
/ \
3 7
/ \
2 4Suppose:
k = 3Step 1
Start at 5.
Go left.
5
/
3Step 2
Go left again.
5
/
3
/
2There is no further left child.
Visit 2.
Visited = 2
index = 1Step 3
Return to 3.
Visit it.
Visited = 3
index = 2Step 4
Go right.
Visit 4.
Visited = 4
index = 3Since
index == kthe answer is
4Why does inorder traversal work?
Because BSTs are already partially sorted.
Every node satisfies:
Left < Node < RightSo visiting
Left
Node
Rightnaturally produces values from smallest to largest.
This property is unique to BSTs.
Time Complexity
Every node is visited at most once.
Time
O(n)Space
O(h)where h is the tree height.
- Balanced BST →
O(log n) - Skewed BST →
O(n)
The recursive call stack uses this space.
Approach 2 — Iterative Inorder Traversal (Recommended)
The recursive solution is elegant, but interviewers also expect you to know how to perform inorder traversal iteratively.
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
stack = []
curr = root
while curr or stack:
while curr:
stack.append(curr)
curr = curr.left
curr = stack.pop()
k -= 1
if k == 0:
return curr.val
curr = curr.rightThis simulates recursion using an explicit stack.
Why while curr or stack?
This is the standard iterative inorder template.
We continue while either:
- we still have nodes to explore (
curr), or - there are previously saved nodes waiting in the stack.
If both become empty, the traversal is complete.
Step-by-Step Example
Using the tree:
4
/ \
2 6
/ \ / \
1 3 5 7Initially:
curr = 4
stack = []Go as far left as possible
Push every left node.
Push 4
Push 2
Push 1Stack:
[4, 2, 1]Pop
Pop 1.
Visited = 1This is the smallest value.
Then move to its right child.
There isn't one.
Continue
Pop 2.
Visited = 2Move to 3.
Push 3.
Pop 3.
Visited = 3Continue.
Eventually the visitation order becomes
1
2
3
4
5
6
7Exactly the same order as recursive inorder traversal.
Why not use a normal DFS?
A normal DFS like this:
stack = [root]
while stack:
node = stack.pop()
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)does not preserve sorted order.
It simply visits nodes in depth-first order.
For example, it might produce:
4
6
7
5
2
3
1or another DFS ordering depending on how children are pushed.
That ordering has nothing to do with the sorted values in the BST, so you cannot use it to find the kth smallest element.
The crucial insight is that this problem requires an inorder traversal, not just any DFS.
Common Mistakes
Forgetting inorder traversal
Using preorder or postorder won't produce sorted values.
Starting the counter incorrectly
Most solutions count from 1.
You can also start at 0 and increment before checking, as in your recursive solution.
Both approaches work as long as you're consistent.
Confusing tree traversal with array indexing
The problem states that k is 1-indexed.
This doesn't mean the tree itself is indexed.
It simply means:
1st smallest
2nd smallest
3rd smallest
...There is no "0th smallest" node.
Which solution should you know?
For interviews:
- ✅ Understand why inorder traversal gives sorted order.
- ✅ Be comfortable writing the recursive inorder DFS.
- ✅ Learn the iterative inorder template, as it's the standard non-recursive solution.
If you remember just one iterative tree traversal pattern, make it this inorder template—it appears in many BST interview problems.
Final Takeaways
- A BST's inorder traversal visits nodes in ascending order.
- The kth node visited during inorder traversal is the kth smallest element.
- The recursive solution is concise and easy to understand.
- The iterative solution uses a stack to simulate recursion and is the standard interview approach.
- Ordinary DFS traversal is not enough—you specifically need inorder traversal to preserve the BST's sorted property.