Given the root
of a Binary Search Tree (BST), return the minimum difference between the values of any two different nodes in the tree.
For example:
Consider the following BST:
4
/ \
2 6
/ \
1 3
The minimum difference is 1
(between nodes 2 and 3, or 1 and 2).
As another example, consider this BST:
1
\
48
/ \
12 49
The minimum difference here is 1
(between nodes 48 and 49).
Constraints:
[2, 100]
.0 <= Node.val <= 10^5
Write a function that efficiently finds the minimum difference between any two nodes in the given BST.
When 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:
To find the smallest difference between values in the tree, a brute force approach involves looking at every possible pair of values. We will find every value in the tree, then calculate the difference between each pair. We'll keep track of the smallest difference we've seen so far.
Here's how the algorithm would work step-by-step:
def minimum_distance_between_bst_nodes_brute_force(root):
tree_values = []
def inorder_traversal(node):
if node:
inorder_traversal(node.left)
tree_values.append(node.val)
inorder_traversal(node.right)
inorder_traversal(root)
# Initialize the minimum difference to a very large value.
minimum_difference = float('inf')
# Iterate through all possible pairs of nodes.
for first_node_index in range(len(tree_values)):
for second_node_index in range(first_node_index + 1, len(tree_values)):
# Avoid comparing the same node with itself
difference = abs(tree_values[first_node_index] - tree_values[second_node_index])
# Update the minimum difference if a smaller difference is found.
if difference < minimum_difference:
minimum_difference = difference
return minimum_difference
The key to solving this efficiently is to realize we don't need to compare every single pair of nodes in the tree. Because it's a Binary Search Tree, nodes are ordered, so we just need to look at adjacent nodes in the sorted order to find the minimum difference.
Here's how the algorithm would work step-by-step:
def minimum_distance_between_bst_nodes(root):
minimum_difference = float('inf')
previous_node_value = None
def in_order_traversal(node):
nonlocal minimum_difference
nonlocal previous_node_value
if not node:
return
in_order_traversal(node.left)
# We're at the "current" node in sorted order
if previous_node_value is not None:
difference = abs(node.val - previous_node_value)
# Update minimum distance
minimum_difference = min(minimum_difference, difference)
# Store the current node's value for the next comparison
previous_node_value = node.val
in_order_traversal(node.right)
# Traverse the tree in-order to visit nodes in sorted order.
in_order_traversal(root)
return minimum_difference
Case | How to Handle |
---|---|
Null or empty BST | Return positive infinity as there's no distance to calculate. |
BST with only one node | Return positive infinity because a minimum distance requires at least two nodes. |
BST with only two nodes | Calculate the absolute difference between the two nodes' values directly. |
BST with many nodes and very small minimum difference | The in-order traversal approach will find the smallest difference because it compares adjacent nodes in sorted order. |
BST with nodes having duplicate values | The in-order traversal considers duplicates and calculates the distance which could be zero. |
BST with integer values near the maximum/minimum integer limits (Integer Overflow) | Use long data type to store the node values or the absolute difference to prevent integer overflow during subtraction. |
Highly skewed BST (essentially a linked list) | The in-order traversal will still find the minimum difference by comparing adjacent nodes after sorting. |
BST where all node values are the same | The minimum difference between nodes would be zero as all adjacent nodes in the in-order traversal would have the same value. |