Skip to content
intermediatePhase 4 · Trees & Heaps

Binary Search Tree

Master BST operations, validation, and balanced tree concepts.

1h 15m
6 problems
Topic Progress0%

BST Properties and Operations

A Binary Search Tree (BST) is a binary tree where for every node:

  • All values in left subtree < node value
  • All values in right subtree > node value

BST Node (same as TreeNode)

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) { this.val = val; }
}

Visual Example

        8
       / \
      3   10
     / \\    \
    1   6    14
       / \\   /
      4   7 13

Search Operation - O(log n) average

public TreeNode search(TreeNode root, int target) {
    if (root == null || root.val == target) return root;
    if (target < root.val) return search(root.left, target);
    return search(root.right, target);
}

Insert Operation - O(log n) average

public TreeNode insert(TreeNode root, int val) {
    if (root == null) return new TreeNode(val);
    if (val < root.val) {
        root.left = insert(root.left, val);
    } else if (val > root.val) {
        root.right = insert(root.right, val);
    }
    return root;
}

Delete Operation - O(log n) average

Three cases:

  1. Leaf node: Simply remove
  2. One child: Replace with child
  3. Two children: Replace with in-order successor (smallest in right subtree)
public TreeNode delete(TreeNode root, int key) {
    if (root == null) return null;

    if (key < root.val) {
        root.left = delete(root.left, key);
    } else if (key > root.val) {
        root.right = delete(root.right, key);
    } else {
        // Node to delete found
        // Case 1 & 2: zero or one child
        if (root.left == null) return root.right;
        if (root.right == null) return root.left;
        // Case 3: two children
        TreeNode successor = findMin(root.right);
        root.val = successor.val;
        root.right = delete(root.right, successor.val);
    }
    return root;
}

private TreeNode findMin(TreeNode root) {
    while (root.left != null) root = root.left;
    return root;
}

Find Min and Max

public TreeNode findMin(TreeNode root) {
    while (root.left != null) root = root.left;
    return root;
}

public TreeNode findMax(TreeNode root) {
    while (root.right != null) root = root.right;
    return root;
}

Complexity Summary

Operation Average Worst (skewed)
Search O(log n) O(n)
Insert O(log n) O(n)
Delete O(log n) O(n)

The worst case occurs when the tree becomes a linked list (skewed tree).

BST Validation and Conversion

Validate BST

Wrong approach: Just check left < node < right. Must verify entire subtree.

Correct approach: Pass valid range down.

public boolean isValidBST(TreeNode root) {
    return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
}

private boolean validate(TreeNode node, long min, long max) {
    if (node == null) return true;
    if (node.val <= min || node.val >= max) return false;
    return validate(node.left, min, node.val) &&
           validate(node.right, node.val, max);
}

In-order Validation (Alternative)

private TreeNode prev = null;

public boolean isValidBST(TreeNode root) {
    if (root == null) return true;
    if (!isValidBST(root.left)) return false;
    if (prev != null && root.val <= prev.val) return false;
    prev = root;
    return isValidBST(root.right);
}

BST to Sorted Array

In-order traversal gives sorted order:

public List<Integer> bstToArray(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    inorder(root, result);
    return result;
}

private void inorder(TreeNode root, List<Integer> result) {
    if (root == null) return;
    inorder(root.left, result);
    result.add(root.val);
    inorder(root.right, result);
}

Sorted Array to Balanced BST

public TreeNode sortedArrayToBST(int[] nums) {
    return buildBST(nums, 0, nums.length - 1);
}

private TreeNode buildBST(int[] nums, int left, int right) {
    if (left > right) return null;
    int mid = left + (right - left) / 2;
    TreeNode node = new TreeNode(nums[mid]);
    node.left = buildBST(nums, left, mid - 1);
    node.right = buildBST(nums, mid + 1, right);
    return node;
}

In-order Successor

public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
    TreeNode successor = null;
    while (root != null) {
        if (p.val < root.val) {
            successor = root;
            root = root.left;
        } else {
            root = root.right;
        }
    }
    return successor;
}

Key Insight

BST property enables O(log n) operations because each comparison eliminates half the tree. The in-order traversal of a BST always produces sorted output.

Practice Problems

0/3solved
Validate Binary Search Tree
BST Validation with Range

Given the root of a binary tree, determine if it is a valid BST.

Example:

Input: root = [2,1,3]

Output: true

Left subtree (1) < 2, right subtree (3) > 2.

Optimal Solution — O(n) time, O(h) space

Validate with min/max range

class Solution {
    public boolean isValidBST(TreeNode root) {
        return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    private boolean validate(TreeNode node, long min, long max) {
        if (node == null) return true;
        if (node.val <= min || node.val >= max) return false;
        return validate(node.left, min, node.val) && validate(node.right, node.val, max);
    }
}

Edge Cases:

  • Single node
  • Left child equal to root
  • Right child equal to root
Kth Smallest Element in a BST
In-order Traversal

Given the root of a BST and an integer k, return the kth smallest element.

Example:

Input: root = [3,1,4,null,2], k = 1

Output: 1

In-order: 1,2,3,4. First is 1.

Optimal Solution — O(k + h) time, O(h) space

Iterative in-order traversal

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode curr = root;
        while (curr != null || !stack.isEmpty()) {
            while (curr != null) { stack.push(curr); curr = curr.left; }
            curr = stack.pop();
            if (--k == 0) return curr.val;
            curr = curr.right;
        }
        return -1;
    }
}

Edge Cases:

  • k == 1
  • k == n
  • All nodes left skewed
Lowest Common Ancestor of a BST
BST Property

Given a BST and two nodes p and q, find their lowest common ancestor.

Example:

Input: root = [6,2,8,0,4,7,9,null,null,null,3,5], p=2, q=8

Output: 6

2 and 8 are in different subtrees, so LCA is root.

Optimal Solution — O(h) time, O(1) space

Use BST property: if both < root, go left; if both > root, go right

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while (root != null) {
            if (p.val < root.val && q.val < root.val) root = root.left;
            else if (p.val > root.val && q.val > root.val) root = root.right;
            else return root;
        }
        return null;
    }
}

Edge Cases:

  • One node is ancestor of other
  • Same values
  • p == q

Quiz

1. What is the in-order traversal of a valid BST?

Question 1 options

2. What is the worst-case time complexity for search in a BST?

Question 2 options

3. What is the primary purpose of Binary Search Tree?

Question 3 options

4. What is a common mistake when implementing Binary Search Tree?

Question 4 options

Flashcards

Question

What is the BST property?

Answer

For every node: all values in left subtree < node value < all values in right subtree. This enables O(log n) search.

Question

Why is the naive BST validation (left < node < right) wrong?

Answer

It only checks immediate children. A node in the left subtree could be greater than an ancestor. Must validate entire subtree ranges.

Question

What is Binary Search Tree?

Answer

Binary Search Tree is a key concept in software engineering.

Question

When to use Binary Search Tree?

Answer

Use Binary Search Tree when building production systems that require reliability, scalability, and maintainability.

Question

Binary Search Tree best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1.BST enables O(log n) search by comparing and eliminating half each time
  • 2.Validation requires passing valid ranges, not just checking children
  • 3.In-order traversal of BST produces sorted order
  • 4.Delete operation uses in-order successor for two-child case

Interview Tips

  • Use Long.MIN_VALUE/MAX_VALUE for initial bounds to handle edge values
  • Clarify if BST allows duplicates (usually strict inequality)
  • Mention that unbalanced BST degenerates to linked list
  • Know how to find in-order successor both with and without parent pointer

Cheat Sheet

Binary Search Tree Cheat Sheet

BST Property: For every node: left subtree values < node < right subtree values

Operations (Average / Worst):

  • Search: O(log n) / O(n)
  • Insert: O(log n) / O(n)
  • Delete: O(log n) / O(n)

Delete Cases:

  1. Leaf → remove
  2. One child → replace with child
  3. Two children → replace with in-order successor (min of right subtree)

Validation Template:

boolean validate(TreeNode node, long min, long max) {
    if (node == null) return true;
    if (node.val <= min || node.val >= max) return false;
    return validate(node.left, min, node.val) &&
           validate(node.right, node.val, max);
}

Key Facts:

  • In-order traversal → sorted output
  • Sorted array → balanced BST via middle element
  • In-order successor: smallest node greater than given node
  • Worst case O(n) when tree is skewed → use AVL/Red-Black