Given the root of a binary search tree and a target value, return the value in the BST that is closest to the target.
You are guaranteed to have only one unique value in the BST that is closest to the target.
Example 1:
Input: root = [4,2,5,1,3], target = 3.714286
Output: 4
Example 2:
Input: root = [1], target = 4.428571
Output: 1
Constraints:
[1, 104].0 <= Node.val <= 109-109 <= target <= 109When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We want to find the value in the tree that's closest to a given target value. The brute force way to do this is to look at every single value in the tree and compare it to the target. Then we just pick the value that's closest.
Here's how the algorithm would work step-by-step:
def closest_value_brute_force(root, target):
tree_values = []
def inorder_traversal(node):
if node:
inorder_traversal(node.left)
tree_values.append(node.val)
inorder_traversal(node.right)
# Extract all the values from the BST into a list
inorder_traversal(root)
closest_value = tree_values[0]
min_difference = abs(tree_values[0] - target)
for current_value in tree_values[1:]:
# Calculate the absolute difference to find closest
current_difference = abs(current_value - target)
# Update if we've found a closer value
if current_difference < min_difference:
min_difference = current_difference
closest_value = current_value
return closest_valueThe problem asks us to find the node in a binary search tree that is closest to a given target value. We can efficiently find this value by leveraging the properties of a binary search tree to eliminate large portions of the tree from our search.
Here's how the algorithm would work step-by-step:
def find_closest_value_in_bst(tree_node, target):
closest_value = tree_node.val
current_node = tree_node
while current_node:
# Keep track of the closest value so far.
if abs(target - current_node.val) < abs(target - closest_value):
closest_value = current_node.val
# Traverse left if the target is smaller.
if target < current_node.val:
current_node = current_node.left
# Traverse right if the target is bigger.
elif target > current_node.val:
current_node = current_node.right
# Target matches current node; it's the closest.
else:
return current_node.val
return closest_value| Case | How to Handle |
|---|---|
| Empty tree (root is null) | Return null or throw an exception if no valid node can be found in an empty tree. |
| Tree with only the root node | Return the root node's value directly as it's the closest. |
| Target value is smaller than the smallest value in the tree | Traverse to the leftmost leaf and return its value. |
| Target value is larger than the largest value in the tree | Traverse to the rightmost leaf and return its value. |
| BST contains duplicate values | The standard BST traversal handles duplicates without issue in finding the closest value. |
| Target is exactly the value of a node in the BST | Return the node's value immediately as it's the closest. |
| Integer overflow if target is very large and node values are very small or vice versa | Use long data type for difference calculations to avoid potential overflow. |
| Large BST with highly skewed distribution (e.g., almost a linked list) | An iterative approach is generally preferred to a recursive one in very deep trees to avoid stack overflow. |