We have a binary search tree and a target value, and we need to find the node whose value matches the target. If we find it, we return that node (which effectively returns the entire subtree rooted at it). If no match exists, we return null.
The detail that matters is that this is a binary search tree, not just any binary tree. In a BST, for every node, all values in its left subtree are smaller and all values in its right subtree are larger. This ordering property is what makes binary search possible on a tree. Instead of checking every node, we can decide at each step which direction to go, eliminating one entire subtree each time.
That ordering is what lets us do better than visiting every node.
1 <= number of nodes <= 5000 -- The tree is small, so even a full O(n) traversal runs fast. The BST structure lets us avoid most of that work.root is a binary search tree -- This guarantees the ordering property that lets us prune one subtree at every step.1 <= Node.val <= 10^7 and 1 <= val <= 10^7 -- All values are positive integers in the same range, so no overflow or negative-value handling is needed. The comparisons val < root.val fit comfortably in a 32-bit integer.Ignore the BST property entirely and treat this as a regular binary tree. We visit every node using DFS, and when we find a node whose value matches val, we return it. If we exhaust the tree without a match, we return null.
This is the approach for a generic binary tree, where no ordering exists to guide the search. It works on a BST too, but it ignores the structure we were given.
val, return the current node.The brute force visits both subtrees at every node. In a BST, when val is less than the current node's value, it cannot be in the right subtree. The next approach uses that ordering to pick a single direction at each step.
Instead of searching both subtrees, we compare val to the current node's value and pick one direction:
val equals the node's value, we found it. Return the node.val is less than the node's value, the target can only be in the left subtree, since everything to the right is larger.val is greater than the node's value, the target can only be in the right subtree.This is binary search applied to a tree instead of an array. At each step we discard one entire subtree, which cuts the work from O(n) to O(h), the height of the tree (O(log n) when the tree is balanced).
val, return the current node.val is less than the current node's value, recursively search the left subtree.val is greater than the current node's value, recursively search the right subtree.Skipping a subtree is safe because the BST invariant is recursive: it holds not just for the current node's direct children but for every descendant. When val < root.val, every value in the right subtree (the root's right child and all of its descendants) is greater than root.val, hence greater than val. So the target cannot be there, and discarding it loses nothing.
This recursive version uses O(h) space on the call stack. Because each recursive call is the last action the function takes, we can replace it with a loop and remove the stack entirely.
The recursive solution is tail-recursive: each recursive call is the last action before the function returns, and its result is returned unchanged. That means no work waits on the call stack, so we can convert it into a while loop. Instead of recursing, we move a pointer to the next node to examine.
The iterative version runs the same comparison-and-branch logic without building a call stack, which brings space down to O(1) regardless of how deep the tree is.
current to the root.current is not null:current.val equals val, return current.val is less than current.val, move current to current.left.current to current.right.