Search in a Binary Search Tree
EasyPrompt
You are given the root of a binary search tree (BST) and an integer val.
Find the node in the BST that the node's value equals val and return the subtree rooted with that node. If such a node does not exist, return null.
Example 1:
Input: root = [4,2,7,1,3], val = 2
Output: [2,1,3]Example 2:
Input: root = [4,2,7,1,3], val = 5
Output: []
Constraints:
- The number of nodes in the tree is in the range
[1, 5000]. 1 <= Node.val <= 107rootis a binary search tree.1 <= val <= 107
Approaches
3 approaches with complexity analysis and trade-offs.
This is an iterative version of the optimized BST search. It uses a loop instead of recursion to traverse the tree, which eliminates the recursion call stack overhead and reduces space complexity to a constant.
Algorithm
- Initialize a
currentpointer to theroot. - Loop as long as
currentis notnullandcurrent.valis not equal toval. - Inside the loop, if
valis less thancurrent.val, updatecurrenttocurrent.left. - Otherwise (if
valis greater thancurrent.val), updatecurrenttocurrent.right. - After the loop, return the
currentpointer.
Walkthrough
We initialize a pointer, current, to the root of the tree. We then enter a loop that continues as long as current is not null. Inside the loop, we compare val with current.val.
- If
valis equal tocurrent.val, we've found the node and break the loop. - If
valis less thancurrent.val, we know the target must be in the left subtree, so we updatecurrenttocurrent.left. - If
valis greater thancurrent.val, we updatecurrenttocurrent.right. The loop effectively traverses a single path from the root down towards the potential location of the node. When the loop terminates,currentwill either point to the found node or benullif the value doesn't exist in the tree. We then returncurrent.
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */class Solution { public TreeNode searchBST(TreeNode root, int val) { TreeNode current = root; while (current != null && current.val != val) { if (val < current.val) { current = current.left; } else { current = current.right; } } return current; }}Complexity
Time
O(H), where H is the height of the tree. Similar to the recursive approach, this is O(log N) for a balanced tree and O(N) for a skewed tree.
Space
O(1). This is the main advantage over the recursive approach. We only use a single pointer to traverse the tree, so the space used is constant regardless of the tree's size or structure.
Trade-offs
Pros
Most efficient in terms of space complexity (O(1)).
Avoids potential stack overflow errors for very deep trees.
Generally faster in practice due to no function call overhead.
Cons
The code might be slightly less intuitive for some developers compared to the direct recursive translation of the search logic.
Solutions
Solution
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public TreeNode searchBST ( TreeNode root , int val ) { if ( root == null || root . val == val ) { return root ; } return root . val < val ? searchBST ( root . right , val ) : searchBST ( root . left , val ); } }Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.