150NeetCode 150

57.Kth Smallest Element in a BST

MediumBlind 75Trees ยท 12/15

Problem

Given the root of a binary search tree and an integer k, return the k-th smallest value (1-indexed) among all node values in the tree.

Examples

Input:  root = [3,1,4,null,2], k = 1
Output: 1
Input:  root = [5,3,6,2,4,null,null,1], k = 3
Output: 3
Explanation: Sorted values are 1, 2, 3, 4, 5, 6; the 3rd is 3.

Constraints

  • The number of nodes in the tree is n.
  • 1 <= k <= n <= 10^4
  • 0 <= Node.val <= 10^4

Follow-up: if the BST is modified often (inserts/deletes) and you need the k-th smallest frequently, store the size of each subtree in its node; then each query takes O(h).

๐Ÿ’ก Key Insight

An in-order traversal of a BST visits values in ascending order. So the k-th node popped by in-order is the answer. With an explicit stack we can stop as soon as we have popped k nodes, doing only O(h + k) work instead of traversing the whole tree.

Brute Force (Collect and Sort)

TimeO(n log n)SpaceO(n)

Intuition

Ignore the BST property: gather every value with any traversal, sort the list, and index position k - 1.

Algorithm

  1. Traverse the tree and append every value to values.
  2. Sort values.
  3. Return values.get(k - 1).

Visualization

root = [5,3,6,2,4,null,null,1]
pre-order collect: [5, 3, 2, 1, 4, 6]
sorted:            [1, 2, 3, 4, 5, 6]
k = 3 -> index 2 -> 3

Code

java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int kthSmallest(TreeNode root, int k) {
        List<Integer> values = new ArrayList<>();
        collect(root, values);
        Collections.sort(values);
        return values.get(k - 1);
    }

    private void collect(TreeNode node, List<Integer> values) {
        if (node == null) {
            return;
        }
        values.add(node.val);
        collect(node.left, values);
        collect(node.right, values);
    }
}

Complexity

  • Time: O(n log n) โ€” dominated by sorting.
  • Space: O(n) โ€” the list of values.

Complexity Comparison

Approach Time Space
Brute Force (Collect and Sort) O(n log n) O(n)
Recursive In-Order with Counter O(h + k) O(h)
Iterative In-Order with Stack O(h + k) O(h)

Common Pitfalls

  • Off-by-one: k is 1-indexed, so the answer is values.get(k - 1) or the pop where k reaches 0.
  • Using pre-order or level order and expecting sorted output โ€” only in-order is sorted for a BST.
  • In the recursive version, not stopping after finding the answer โ€” the traversal keeps running, and if answer is overwritten later you get the wrong value.
  • Declaring count as static โ€” it carries over between LeetCode test cases.