Binary Search Trees · 3 of 22
Find min and max value in a BST
The smallest number in a sorted tree lives at the end of the always-go-left road, and the biggest at the end of the always-go-right road.
- Simple way
- time O(n)
room O(h) - Clever way
- time O(h)
room O(1)
The problem, simply
You get a binary search tree (BST): at every spot, the left side is smaller and the right side is bigger. Give back the smallest number and the biggest number in the tree.
A story to remember it
Picture it
The always-left road ends at 1, the smallest. The always-right road ends at 14, the biggest. Note that 14 still has a child, 13, on its left. It has no right child, and that is all that matters.
- answer
Examples
A normal tree
- In
[8, 3, 10, 1, 6, null, 14, null, null, 4, 7, 13]- Out
min = 1, max = 14
Left, left: 8, 3, 1. Right, right: 8, 10, 14.
The smallest is not a leaf
- In
[5, 2, 8, null, 3]- Out
min = 2, max = 8
2 has no left child, so it is the smallest, even though 3 hangs below it on the right. 3 is bigger than 2, as the rule says.
The top is the smallest
- In
[4, null, 6, null, 9]- Out
min = 4, max = 9
The top has no left child. The always-left road has zero steps.
Only one number
- In
[7]- Out
min = 7, max = 7
The same spot is both ends.
Empty tree
- In
[]- Out
no answer
There is no smallest number. Decide up front: return null, throw an error, or return a special value. Say which one out loud.
Way 1: the simple way
Visit every spot and remember the smallest and biggest number seen so far. This works for any tree, sorted or not.
- Start with
minas the biggest possible number andmaxas the smallest possible number. - Visit every spot. Update
minandmax. - Return both.
class Solution {
private int min, max;
public int[] findMinMax(TreeNode root) {
if (root == null) return null; // empty tree: no answer
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
visit(root);
return new int[] { min, max };
}
private void visit(TreeNode node) {
if (node == null) return;
min = Math.min(min, node.val);
max = Math.max(max, node.val);
visit(node.left);
visit(node.right);
}
}How long it takes: every spot once, O(n). Extra room: the recursion goes as deep as the tree, O(h).
Way 2: the clever way
Use the slope of the playground.
- For the smallest: start at the top, keep moving to
leftwhile there is a left child. Where you stop is the smallest. - For the biggest: start at the top, keep moving to
rightwhile there is a right child. Where you stop is the biggest.
Why it is right: everything on the left of a spot is smaller than it. So if a spot has a left child, it cannot be the smallest. The first spot with no left child has nothing smaller anywhere below it, and everything above it on the road was bigger.
Slide left for the smallest, climb right for the biggest
01 / 06
Smallest first. Start at the top, 8. It has a left child, so something smaller exists.
- min so far
- 8
- looking now
- seen
- answer
- path
- ignored
class Solution {
public int[] findMinMax(TreeNode root) {
if (root == null) return null; // empty tree: no answer
TreeNode lo = root;
while (lo.left != null) lo = lo.left; // slide left
TreeNode hi = root;
while (hi.right != null) hi = hi.right; // climb right
return new int[] { lo.val, hi.val };
}
}How long it takes: each road is at most the height of the tree, O(h). That is about log n for a balanced tree and n for a stick. Extra room: two fingers, O(1).
Watch out for
- An empty tree. Check for
nullbefore the loops, or you crash onlo.left. - Using
while (lo != null)and then readinglo.val. That loop runs off the tree. Testlo.left, notlo. - For a normal binary tree (not a BST), this trick is wrong. You must use Way 1.
What interviewers ask next
- Find the second smallest. If the smallest has a right child, the answer is the leftmost spot of that right side. Otherwise it is the parent of the smallest. Or walk in sorted order and stop at the second number.
- Find the smallest number bigger than
x(the ceiling). Walk down from the top. Each time you go left, remember the spot. The last remembered spot is the answer. - Return the nodes instead of the values, so the caller can delete them. Same loops, return
loandhi. - In Java's
TreeMap, what are these?firstKey()andlastKey(). They walk the same roads.
Remember this
Grown-up words: the downhill left path is the left subtree, the end of the always-left road is the leftmost node (the minimum), the end of the always-right road is the rightmost node (the maximum), and the number of posts on the road is the height h.