Problem Statement
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 no such a node exists, return null
.
Examples
Example 1:
Input:
Tree:
4
/ \
2 7
/ \
1 3
val = 2
Output:
2
/ \
1 3
Explanation: The node with value 2 is found in the BST, and the subtree rooted at this node is returned.
Example 2:
Input:
Tree:
4
/ \
2 7
/ \
1 3
val = 5
Output: null
Different Approaches
1️⃣ Iterative Approach
Intuition:
In a Binary Search Tree (BST), the key property is that for any given node N, all nodes in its left subtree contain values smaller than N, while all nodes in its right subtree hold values greater than N. This structure facilitates an efficient search for a value X, which can be understood through three distinct scenarios:
1. If the value at node N matches X, then N is the target node.
2. If the value at node N is less than X, the search must proceed to the right subtree, as X cannot exist in the left subtree.
3. If the value at node N is greater than X, the search must continue in the left subtree, since X cannot be found in the right subtree.
Approach:
- Initiate a traversal of the tree using a while loop, conditioned on the root being non-NULL and the root's data not matching X.
- If the root's data is less than X, shift the focus to the right child of the root.
- If the root's data exceeds X, redirect the search to the left child of the root.
- Upon exiting the loop, if the root is NULL, it indicates that X is not present in the tree, and the function should return NULL. Otherwise, return the node containing the value X.
Code:
// Definition for a binary tree node.
struct TreeNode {
int data;
TreeNode *left;
TreeNode *right;
TreeNode(int val) : data(val), left(nullptr), right(nullptr) {}
};
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
// Traverse the tree until we find the node
// with the given value or reach the end
while (root != nullptr && root->data != val) {
// Move to the left or right child
// depending on the value comparison
root = (root->data > val) ? root->left : root->right;
}
// Return the found node or nullptr if not found
return root;
}
};
// Example usage
int main() {
// Creating a simple BST for demonstration
TreeNode* root = new TreeNode(4);
root->left = new TreeNode(2);
root->right = new TreeNode(7);
root->left->left = new TreeNode(1);
root->left->right = new TreeNode(3);
Solution sol;
TreeNode* result = sol.searchBST(root, 2);
if (result) {
std::cout << "Node found with value: " << result->data << std::endl;
} else {
std::cout << "Node not found" << std::endl;
}
// Clean up memory (omitted for brevity)
return 0;
}
Complexity Analysis:
- Time Complexity:
O(log2(N))
: The time complexity isO(log2(N))
in a balanced BST since the search space is halved at each step. However, in the worst case (skewed tree), it can beO(N)
. - Space Complexity:
O(1)
: The space complexity isO(1)
as the search is performed iteratively without using additional space.
2️⃣ Recursive Approach
Intuition:
The recursive approach uses the BST property to navigate the tree:
- If the value of the current node matches
val
, return the current node. - If
val
is smaller, search in the left subtree. - If
val
is larger, search in the right subtree.
Approach:
- Start at the root.
- If the root is
nullptr
, returnnullptr
. - Compare
val
with the root's value:- If equal, return the root.
- If less, recursively search in the left subtree.
- If greater, recursively search in the right subtree.
Code:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
// Base case: root is nullptr or root's value matches val
if (!root || root->data == val) {
return root;
}
// Recursive search in the left or right subtree
if (val < root->data) {
return searchBST(root->left, val);
} else {
return searchBST(root->right, val);
}
}
};
Complexity Analysis:
- Time Complexity:
O(h)
, whereh
is the height of the BST.- In the worst case (unbalanced tree),
h=N
. - In the best case (balanced tree),
h=logN
.
- In the worst case (unbalanced tree),
- Space Complexity:
O(h)
due to the recursive call stack.