Problem Walkthrough

Kth Smallest Element in BST LeetCode 230

Inorder traversal of a BST visits nodes in ascending order. Count nodes during traversal and return the k-th one. Iterative stack approach allows early termination.

7 min read|

Kth Smallest in BST

LeetCode 230

Problem Overview

LeetCode 230 — Kth Smallest Element in a BST — gives you the root of a binary search tree and an integer k. Return the k-th smallest value (1-indexed) among all nodes in the BST.

The fundamental property of a BST is that an inorder traversal (left, root, right) visits nodes in ascending order. The k-th node visited during inorder traversal is the k-th smallest element. No sorting needed.

Two implementations: recursive inorder (simple but traverses the entire tree) and iterative inorder with a stack (can stop as soon as the k-th element is found). The iterative approach is preferred for its early termination capability.

  • Input: BST root and integer k (1-indexed)
  • Return the k-th smallest value in the BST
  • Inorder traversal visits BST nodes in sorted order
  • Iterative stack allows O(H+k) early termination
  • All node values are unique

Why Inorder Traversal Works

In a BST, every node's left subtree contains only smaller values, and the right subtree contains only larger values. Inorder traversal recursively visits left subtree, then the current node, then the right subtree.

This left-root-right order produces values in ascending sequence. For example, a BST with values [1, 2, 3, 4, 5, 6] produces inorder: 1, 2, 3, 4, 5, 6. The k-th value in this sequence is the k-th smallest.

The connection between BSTs and sorted order is the core insight. Any BST problem that asks about rank, order, or position can be solved by leveraging inorder traversal.

💡

BST Inorder = Sorted Order

This property is the most important BST fact for interviews. Whenever you see "k-th smallest" or "k-th largest" in a BST, think inorder traversal immediately. For k-th largest, use reverse inorder (right, root, left).

Iterative Inorder with Stack

Initialize an empty stack and a pointer curr = root. While the stack is non-empty or curr is not null: push all left children of curr onto the stack (go as far left as possible). Pop the top node — this is the next smallest element. Decrement k. If k reaches 0, return the node's value.

If k is not yet 0, move curr to the popped node's right child and repeat. The right subtree contains the next larger values. The stack stores ancestors waiting to be processed after their left subtrees.

This iterative approach visits exactly H + k nodes in the worst case: H to reach the leftmost node (going down the left spine), then k to traverse to the k-th element. It stops immediately without processing the remaining n - k nodes.

Step-by-Step Walkthrough

Consider BST: 5 with left child 3 (left: 2 with left: 1, right: 4) and right child 6. k = 3. Stack: []. curr = 5. Push left: 5, 3, 2, 1. Stack: [5, 3, 2, 1]. curr = null.

Pop 1 (k=3→2). Right child is null. Pop 2 (k=2→1). Right child is null. Pop 3 (k=1→0). Return 3! The 3rd smallest element is 3. We only visited 3 nodes out of 6 — the iterative approach saved work.

If k were 5, we would continue: after popping 3, move to right child 4. Push 4. Pop 4 (k=2→1... wait, let me recount). After returning 3 at k=0, we stop. For k=5, we would continue through 4, 5, then into the right subtree to 6.

ℹ️

Early Termination Advantage

When k is small relative to n, the iterative approach is much faster than recursive (which always visits all n nodes). For k=1 (minimum), we only traverse the left spine: O(H) time.

Implementation in Python and Java

Python iterative: stack = []. curr = root. While stack or curr: while curr: stack.append(curr); curr = curr.left. curr = stack.pop(). k -= 1. If k == 0: return curr.val. curr = curr.right.

Python recursive: result = []. def inorder(node): if not node or len(result) >= k: return. inorder(node.left). result.append(node.val). inorder(node.right). inorder(root). return result[k-1]. Simpler but visits all nodes.

Java iterative: Deque<TreeNode> stack = new ArrayDeque<>(). TreeNode curr = root. Same while loop with push-left, pop, decrement k, check, move right. Return value when k reaches 0.

Complexity Analysis

Iterative: O(H + k) time where H is the tree height. We traverse H nodes to reach the leftmost, then k nodes to reach the answer. For a balanced BST, H = log n, so time is O(log n + k). For a skewed BST, H = n.

Space: O(H) for the stack. The stack holds at most H nodes (the height of the tree). For a balanced BST, this is O(log n). For a skewed tree, O(n).

The follow-up asks: what if the BST is modified often (insert/delete) and kthSmallest is called frequently? Augment each node with a count of nodes in its left subtree. Then kthSmallest becomes O(H) without traversal, and updates are O(H) per modification.

YeetCode Flashcard Tip

Kth Smallest in BST is the gateway to BST order-statistics problems. Practice it alongside Validate BST and BST Iterator on YeetCode to master inorder traversal in all its forms.

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now