Last Updated: March 29, 2026
We have a binary search tree and a target value (which can be a decimal), and we need to find which node value is closest to that target. If two node values are equally close, we return the smaller one.
The BST property is the key here. In a BST, every node's left subtree contains only values smaller than the node, and every node's right subtree contains only values larger. This ordering means we don't need to check every single node. If the target is less than the current node, the answer can't be hiding in the right subtree (well, it could be the current node, but nothing further right will be closer). So we can prune our search, much like binary search on a sorted array.
1 <= number of nodes <= 10^4 → With up to 10,000 nodes, even an O(n) traversal is acceptable. But we can do better by leveraging the BST structure.0 <= Node.val <= 10^9 → Node values are non-negative and can be large. No overflow concerns in Java/C++ since we'll use long or double for distance calculations.-10^9 <= target <= 10^9 → Target can be negative even though node values are non-negative. Also, the target is a floating-point number, so the closest node value might not be an exact match.The most straightforward idea is to collect all the values in the BST and then find which one is closest to the target. Since an inorder traversal of a BST gives us values in sorted order, we can traverse the entire tree, store every value, and then scan through the list to find the minimum absolute difference.
This ignores the BST structure for the search itself, essentially treating it as "give me all the values and I'll figure it out." It works, but it's wasteful because we're visiting every node when we don't have to.
We're visiting every single node even though the BST property tells us which direction to search. What if we walked down the tree like a binary search, only visiting one child at each level?
Here's the key insight: in a BST, we can navigate toward the target just like binary search navigates through a sorted array. At each node, we compare the target to the node's value. If the target is smaller, we go left. If it's larger, we go right. Along the way, we keep track of the closest value we've seen.
The beauty of this approach is that we never need to backtrack. At each node, the BST property guarantees that the subtree we skip can't contain a closer value than what we've already found on our path.
The correctness hinges on the BST property. When we decide to go left (because target < node.val), we discard the entire right subtree. Every value in the right subtree is greater than or equal to node.val. Since node.val is already farther from target in the "greater" direction, everything in the right subtree is even farther. The same logic applies in reverse when going right.
So at each level, we make the locally correct decision (go toward where the target would be), and we never skip over a potential answer. The closest value must lie on the path from the root to where the target would be inserted, and that's exactly the path we follow.
closest to the root's value.closest if the current node is nearer to the target (or equally near but smaller).target < node.val, move to the left child. Otherwise, move to the right child.closest.This is the same algorithm expressed recursively, which some find more natural for tree problems.
This is the same algorithm as Approach 2, but expressed recursively. Some people find recursive tree code more natural to write, especially in interviews where you're already thinking about tree problems recursively.
The idea is identical: at each node, update the closest value, then recurse into the appropriate subtree. The recursion naturally stops when we hit a null node.
closest and update if it's nearer (or equally near but smaller).target < node.val, recurse left. Otherwise, recurse right.