Given the root of a binary search tree and an integer key, find the predecessor and successor of key in the BST and return them as a two-element array [predecessor, successor].
key.key.If either does not exist, use -1 in its place. The key may or may not be present in the tree. The tree is given in level-order (breadth-first), using null for missing children.
Input: root = [8, 4, 12, 2, 6, 10, 14], key = 6 Output: [4, 8] The largest value below 6 is 4; the smallest above 6 is 8.
Input: root = [8, 4, 12, 2, 6, 10, 14], key = 2 Output: [-1, 4] 2 is the minimum, so there is no predecessor; the successor is 4.
- The number of nodes is in the range [1, 10^4] - 1 <= Node.val <= 10^5 - All Node.val are unique - 1 <= key <= 10^5
You could flatten the BST to a sorted array (inorder) and scan for the neighbours of key, but that's O(n) time and space. The BST ordering gives a two-descent answer in O(height): keep two candidates and update them as you walk down.
Descend from the root. If the current node is below key, it's a possible predecessor — record it and go right (something bigger but still under key may lie there). If it's above key, it's a possible successor — record it and go left. If you land on key, the true neighbours are in its subtrees: the predecessor is the rightmost node of the left subtree, the successor is the leftmost node of the right subtree.
“Is the key guaranteed to be in the tree?”
Not necessarily — handle both present and absent keys.
“What if there is no predecessor or successor?”
Return -1 for the missing one.
I walk down keeping two candidates: nodes below the key update the predecessor, nodes above update the successor.
If I land on the key, the predecessor is the max of its left subtree and the successor the min of its right.
Worked example — BST [8, 4, 12, 2, 6, 10, 14], key = 6
8 > 6 -> succ = 8, go left 4 < 6 -> pred = 4, go right 6 == 6 -> no left/right child of 6 here -> pred stays 4, succ stays 8 answer = [4, 8]
A node smaller than the key is a predecessor candidate; going right may find a larger-but-still-smaller one.
A node larger than the key is a successor candidate; going left may find a smaller-but-still-larger one.
Predecessor = rightmost of the left subtree; successor = leftmost of the right subtree.
| Sorted inorder scan | Two-descent | |
|---|---|---|
| Idea | Flatten to a sorted array, scan for neighbours | Track two candidates while walking down |
| Time | O(n) | O(height) |
| Space | O(n) | O(1) |
Both return the same pair; the descent uses the ordering to avoid touching every node. Full code is in the Approaches selector below.
Key takeaway
Walk down the BST tracking a predecessor and a successor candidate; below the key updates the predecessor (go right), above updates the successor (go left). On the key, take the extremes of its subtrees. O(height) time, O(1) space.
while node:
if node < key: pred = node; go right
elif node > key: succ = node; go left
else: pred = max(left subtree); succ = min(right subtree); stop