Kth Largest Element in a BST turns one fact about binary search trees into a tiny, elegant traversal. The trick: a BST already holds its values in sorted order if you walk it the right way — so finding the kth largest is just counting nodes as you visit them in descending order.
Problem. Given the root of a binary search tree and an integer k, return the kth largest
value in the tree (1-indexed, so k = 1 is the maximum).
Example: the BST with root 4, children 2 and 6, and leaves 1, 3, 5, 7, with k = 2 → answer
6 (the values largest-first are 7, 6, 5, 4, ..., and the 2nd is 6).
The slow way first
The obvious idea: collect every value into a list, sort it, and pick the kth from the end. That works, but sorting costs O(n log n) and throws away the structure the BST already gives you for free.
The question to ask: what order does a BST visit its values in? A normal in-order walk — left, root, right — visits values in ascending order. We want descending. So we just mirror the walk.
The idea: walk it right, root, left
A reverse in-order traversal — right subtree, then the node, then left subtree — visits the values from largest to smallest. Keep a counter k. Every time we visit a node, decrement k. The moment k hits 0, the node we are standing on is the answer, and we can stop immediately.
The key insight: because we go right before touching the node, the nodes are visited strictly largest-first. So the kth node visited is exactly the kth largest — no sorting, and we stop as soon as we find it.
Walk through it
Step through the animation with k = 2. From root 4 we dive right into 6, then right again into 7 — the largest value, visited first (k: 2 → 1). 7 has no children to its left, so we return up to 6, visit it (k: 1 → 0), and stop. The 2nd largest value is 6.
Pseudocode
k counter starts at the given k
define visit(node):
if node is empty: return nothing
answer = visit(node.right) # larger values first
if answer was found: return it
k = k - 1 # visit this node
if k == 0: return node.value # this is the kth largest
return visit(node.left) # smaller values
return visit(root)The Python solution
def kth_largest(root, k):
self.k = k
def visit(node):
if not node:
return None
right = visit(node.right)
if right is not None:
return right
self.k -= 1
if self.k == 0:
return node.val
return visit(node.left)
return visit(root)self.kholds the live countdown so every recursive call shares one counter.visit(node.right)recurses into the right subtree first — that is what makes the order descending.- If that right call already found the answer, we pass it straight back up and never touch the rest.
self.k -= 1happens when we actually visit this node, after its right subtree is fully done.if self.k == 0is the stopping condition — the currentnode.valis the kth largest, returned immediately.- Only if we have not found it do we descend left into the smaller values.
Complexity
| Case | Time | Notes |
|---|---|---|
| Collect all + sort | O(n log n) (moderate) | ignores BST order |
| Reverse in-order (this solution) | O(h + k) (moderate) | stops as soon as k hits 0 |
O(h) (moderate)We visit at most k nodes plus the height h it takes to reach the largest value, so the work is O(h + k) — and in the worst case (a skewed tree, or large k) that is O(n). The extra space is the recursion stack, O(h), which is O(log n) for a balanced tree.
When this pattern shows up
Any time a problem mentions a BST and ordering — kth smallest, kth largest, the in-order successor, validating a BST, or printing values in sorted order — reach for an in-order traversal. Left-root-right gives ascending; right-root-left gives descending. The "kth" variants just add a counter and an early stop.
Decrement k only when you actually visit a node, not when you enter the function. And remember to
short-circuit: once the answer bubbles up, return it without exploring more nodes, or you lose the early-stop
speed-up.
Practice
In the same tree with k = 1, which node is the answer and how many nodes do we visit before stopping?
1. Which traversal visits a BST values from largest to smallest?
2. When do we decrement k?
3. Why can the search stop early?
4. What is the time complexity in terms of height h and k?