K-th Smallest Value in a BST

Problem

The first line has distinct numbers. Insert them one by one into an empty binary search tree. The second line has the number k. Print the k-th smallest value in the tree (k = 1 is the smallest). Use an in-order walk (left, node, right) and stop as soon as you have counted k nodes.

Constraints

  • 1 <= k <= n <= 1000
  • values are distinct

Examples

Input

5 3 6 2 4 1
3

Output

3

Solutions

Best approachTime O(h + k)Space O(h)

An in-order walk of a BST visits the values from small to big, so the k-th visited node is the answer. Stopping early means we do not need to visit the rest of the tree. Using an explicit stack avoids a deep recursion on long, thin trees.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process a tree.
 * Input   : Line 1: values to insert. Line 2: the query.
 * Output  : The k-th smallest value.
 * Approach: Build a BST, then walk in order.
 * Time    : O(h + k)
 * Space   : O(h)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: A node holds a value and two children. Smaller values go to the left, bigger values go to the right.
        static class Node {
            final long value;
            Node left;
            Node right;

            Node(long value) {
                this.value = value;
            }
        }

        static Node insert(Node root, long value) {
            if (root == null) {
                return new Node(value);
            }
            if (value < root.value) {
                root.left = insert(root.left, value);
            } else {
                root.right = insert(root.right, value);
            }
            return root;
        }

    // This method solves the task. It receives the input and returns the answer.
    static long solve(String[] lines) {
        Node root = null;
        for (String text : lines[0].split(" ")) {
            root = insert(root, Long.parseLong(text));
        }
        int k = Integer.parseInt(lines[1].trim());
        // Step 2: An in-order walk without recursion: go left as far as possible and keep the nodes on a stack.
        java.util.ArrayDeque<Node> stack = new java.util.ArrayDeque<>();
        Node current = root;
        int counted = 0;
        while (current != null || !stack.isEmpty()) {
            while (current != null) {
                stack.push(current);
                current = current.left;
            }
            // Step 3: The node on top of the stack is the next smallest value. Count it.
            current = stack.pop();
            counted++;
            if (counted == k) {
                return current.value;
            }
            // Step 4: After a node, visit its right subtree.
            current = current.right;
        }
        return -1;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(solve(lines));
    }
}
Hints (1)
  1. Why does an in-order walk give sorted values?