Kth Smallest and Largest in BST
Find both the k-th smallest and k-th largest BST values.
Open on GeeksforGeeks ↗Intuition
k-th smallest is the k-th node of inorder (left-node-right); k-th largest is the k-th node of REVERSE inorder (right-node-left). Two early-stopping traversals — or one, since k-th largest = (n−k+1)-th smallest.
In-order gives ascending values; reverse in-order — right, node, left — gives descending. So the k-th largest is the k-th smallest of the mirrored traversal, and one parameterised function answers both. Recognising that a traversal's direction is just a swap of two recursive calls saves writing the second algorithm.
Approach
Forward inorder for smallest
Count nodes as visited; stop at k.
Reverse inorder for largest
Mirror the traversal (right first) — descending stream, stop at k.
Or count once
Knowing n converts largest into a second smallest query; useful when n is cached.
Solution & live demo
Common pitfalls
Sorting all values to pick both
vals = sorted(inorder(root)) return vals[k-1], vals[-k]
inorder(root, False, [0], small) inorder(root, True, [0], large)
A BST is already ordered — re-sorting throws that away and costs O(n log n) plus O(n) space. Each traversal can stop as soon as it has counted k nodes.
Not stopping once the answer is found
def inorder(node, ...):
inorder(node.left, ...)
count[0] += 1
if count[0] == k: out.append(node.val)
inorder(node.right, ...)if not node or out: return ... if count[0] == k: out.append(node.val); return
Without the early exit the traversal continues past the target and the counter keeps advancing, so a later node can be appended too. Checking out at the top prunes every remaining branch.
Passing the counter as a plain integer
def inorder(node, count):
count += 1def inorder(node, reverse, count, out):
count[0] += 1Integers are immutable in Python, so count += 1 rebinds a local and the increment is lost when the frame returns. The count must be shared across the whole traversal — a one-element list (or a class attribute) provides that.
Edge cases
Smallest = leftmost node, largest = rightmost.
Traversal exhausts → report not found.