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.
Input : root = [4, 2, 7, 1, 3] , val = 2
Output : [2, 1, 3]
Explanation :
Input : root = [4, 2, 7, 1, 3] , val = 5
Output : []
Explanation :
Input : root = [10, 2, 12, 1, 4, null, null, null, null, 3] , val = 2
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.
// 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;
}
// Definition for a binary tree node.
public class TreeNode {
int data;
TreeNode left;
TreeNode right;
TreeNode(int val) { data = val; left = null; right = null; }
}
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 != null && 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 null if not found
return root;
}
// Example usage
public static void main(String[] args) {
// 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 = new Solution();
TreeNode result = sol.searchBST(root, 2);
if (result != null) {
System.out.println("Node found with value: " + result.data);
} else {
System.out.println("Node not found");
}
}
}
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.data = val
self.left = left
self.right = right
class Solution:
def searchBST(self, root, val):
# Traverse the tree until we find the node
# with the given value or reach the end
while root is not None and root.data != val:
# Move to the left or right child
# depending on the value comparison
root = root.left if root.data > val else root.right
# Return the found node or None if not found
return root
# Example usage
def main():
# Creating a simple BST for demonstration
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
sol = Solution()
result = sol.searchBST(root, 2)
if result:
print(f"Node found with value: {result.data}")
else:
print("Node not found")
if __name__ == "__main__":
main()
// Definition for a binary tree node.
class TreeNode {
constructor(val = 0, left = null, right = null) {
this.data = val;
this.left = left;
this.right = right;
}
}
class Solution {
searchBST(root, val) {
// Traverse the tree until we find the node
// with the given value or reach the end
while (root !== null && 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 null if not found
return root;
}
}
// Example usage
function main() {
// Creating a simple BST for demonstration
let 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);
let sol = new Solution();
let result = sol.searchBST(root, 2);
if (result) {
console.log("Node found with value: " + result.data);
} else {
console.log("Node not found");
}
}
main();
Time Complexity: O(log2(N)) : The time complexity is O(log2(N)) in a balanced BST since the search space is halved at each step. However, in the worst case (skewed tree), it can be O(N).
Space Complexity: O(1): The space complexity is O(1) as the search is performed iteratively without using additional space.
Q: What if multiple nodes have the same value in the BST?
A: A valid BST does not have duplicate values by definition. If duplicates exist (e.g., in a modified BST with duplicate handling), we might need to return all matching nodes instead of just one.
Q: Why do we not search both left and right subtrees?
A: BST properties guarantee that if val < root.val, it must be in the left subtree (if it exists). Likewise, if val > root.val, it must be in the right subtree. Unlike a normal binary tree, BST only requires searching in one direction, reducing time complexity.
Q: How can this be extended to return the closest value if val does not exist?
A: We can track the closest node encountered while traversing the BST. Instead of returning null, return the node with the smallest absolute difference from val.
Q: How does this problem change if we were searching in a normal binary tree (not a BST)?
A: For a general binary tree, there is no ordering property, so we must perform a full tree traversal (DFS or BFS) instead of binary search. This increases complexity to O(n).