Given the root of a binary search tree and an integer val, return the subtree rooted at the node whose value equals val. If no such node exists, return null (an empty tree).
The tree is given/returned in level-order (breadth-first), using null for missing children.
Input: root = [4, 2, 7, 1, 3], val = 2 Output: [2, 1, 3] 2 is the left child of the root; return its whole subtree.
Input: root = [4, 2, 7, 1, 3], val = 5 Output: [] 5 is not in the tree.
- The number of nodes is in the range [1, 5000] - 1 <= Node.val <= 10^7 - root is a valid BST - 1 <= val <= 10^7
In a BST, each node tells you which way to go: if val is smaller than the current node, the target can only be in the left subtree; if larger, only the right. So searching is a single walk from the root downward — O(height), versus O(n) for a blind scan.
“What do you return?”
The whole subtree rooted at the matching node (not just the value).
“What if val isn't present?”
Return null.
Because it's a BST, I compare val to the current node and go left if smaller, right if larger.
I stop when I find the value or fall off the tree — an O(height) walk.
Worked example — BST [4, 2, 7, 1, 3], val = 2
4
/ \
2 7
/ \
1 3
4 vs 2 -> go left -> 2 == 2 -> return subtree [2, 1, 3]
Smaller than the node ⇒ only the left subtree can contain it; larger ⇒ only the right.
You never backtrack — search is a straight descent.
Balanced ⇒ O(log n); a skewed BST degrades to O(n).
| Recursive descent | Iterative descent | |
|---|---|---|
| Idea | Recurse into the correct child | Loop, moving to the correct child |
| Time | O(height) | O(height) |
| Space | O(height) | O(1) |
Both are O(height); the iterative version uses O(1) space. Full code is in the Approaches selector below.
Key takeaway
Compare val to the node and descend left (smaller) or right (larger) until you match or hit null. O(height) time, O(1) space iteratively.
while node:
if val == node.val: return node
node = node.left if val < node.val else node.right
return null