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.
In a BST, every node's left subtree contains only smaller values and every right subtree only larger ones. This ordering means the search does not have to touch every node. If the target is less than the current node's value, no node in the right subtree can be closer than the current node itself, so that entire subtree can be skipped. The search can proceed like binary search on a sorted array.
1 <= number of nodes <= 10^4 → With up to 10,000 nodes, an O(n) traversal is acceptable, but the BST ordering allows an O(h) search along a single path.0 <= Node.val <= 10^9 → Distances are computed as double. A double represents integers exactly up to 2^53, far above 10^9, so subtracting an integer node value from the target loses no precision.-10^9 <= target <= 10^9 → The target can be negative even though node values are non-negative, and it is a floating-point number, so an exact match may not exist.Collect every value in the tree, then scan the list for the one with the minimum absolute difference from the target, keeping the smaller value on ties. An inorder traversal visits a BST's nodes in sorted order, though this approach only needs the values, not their order.
This treats the tree as a plain container and ignores its ordering during the search, so every node gets visited.
Tree [4, 2, 5, 1, 3] with target = 3.5. Both 3 and 4 sit at distance 0.5 from the target, so this input exercises the tie-breaking rule.
This visits every node even though comparing the target with a node's value already identifies the only subtree that can hold a closer candidate. The next approach uses that comparison to walk a single root-to-leaf path.
A BST supports the same navigation as binary search on a sorted array. At each node, compare the target to the node's value: if the target is smaller, move left; otherwise move right. Along the way, track the closest value seen so far.
This walk never backtracks, so it touches one node per level along a single root-to-leaf path.
When target < node.val, every value in the right subtree is at least node.val, so each of them sits farther above the target than node.val itself. Skipping the right subtree therefore discards no candidate better than the node already examined. The mirror argument applies when moving right.
Because the walk always steps toward the target, both the closest value below the target and the closest value above it (when they exist) appear on the root-to-null search path. The answer must be one of these two neighbors, and the update rule compares both: it keeps the nearer one, and on a tie it keeps the smaller, which matches the problem's tie-breaking requirement.
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.The same input, tree [4, 2, 5, 1, 3] with target = 3.5. The tie between 3 and 4 now resolves during the descent instead of in a separate scan.
The same descent can also be written recursively, passing the running closest value down through the calls.
This is the same descent as Approach 2, written as a recursive function. Each call processes one node: update the closest value, then recurse into the child on the target's side of the current node. A null node ends the recursion and returns the best value found.
The recursive form trades the loop's O(1) space for a call stack that grows with the tree height.
closest and update if it's nearer (or equally near but smaller).target < node.val, recurse left. Otherwise, recurse right.Tree [4, 2, 5, 1, 3] with target = 3.714286, the input from Example 1. The root is already the closest value, so each deeper call leaves closest unchanged.