Lowest Common Ancestor Of A Binary Search Tree
To solve this coding challenge, we need to find the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree (BST). In a BST, for each node, the value of its left subtree nodes will be lesser, and the value of its right subtree nodes will be greater than the node's value. This property of the BST can be leveraged to efficiently determine the LCA of two given nodes.
# Explanation
- Definition Recap :
- The Lowest Common Ancestor (LCA) of two nodes \( p \) and \( q \) in a binary tree is the lowest node that has both \( p \) and \( q \) as descendants, including the node itself.
- Understanding the Binary Search Tree (BST) :
-
For a given node \( n \),
contains nodes with values less than
n.left, andn.valcontains nodes with values greater thann.right.n.val - LCA Property and BST Characteristics :
- Given nodes \( p \) and \( q \):
- If both \( p \) and \( q \) are less than \( n \), then the LCA must be in the left subtree of \( n \).
- If both \( p \) and \( q \) are greater than \( n \), then the LCA must be in the right subtree of \( n \).
- If one is less than \( n \) and the other is greater than \( n \), or one of them is equal to \( n \), then \( n \) is the LCA.
- Algorithm :
- Start with the root of the tree.
- Traverse the tree:
- If both nodes are smaller than the current node, move to the left child.
- If both nodes are larger than the current node, move to the right child.
- If the nodes diverge (one on the left and one on the right) or if one of them equals the current node, the current node is the LCA.
- Initial Setup :
- Start at the root node of the BST.
- Traversal Logic :
- While the current node is not null:
- Compare the values of \( p \), \( q \) with the current node's value.
- Decide whether to move left, move right, or return the current node as the LCA.
- Return the Result :
- The result is the node where the paths to \( p \) and \( q \) diverge or where one of the nodes equals the current node.
- Initialization :
-
Assign the
of the tree to the variable
rootfor traversal.current_node - Loop until LCA is Found or Reaching Null :
-
Check if both
and
node_phave values less thannode_q. If true, move to the left child (current_node.value).current_node.left -
Check if both
and
node_phave values greater thannode_q. If true, move to the right child (current_node.value).current_node.right - If neither condition is met, then either:
-
One node lies on the left and the other on the right, making
the LCA.
current_node -
One node equals
, making
current_nodethe LCA as per the definition it allows the node to be a descendant of itself.current_node - Returning the Result :
-
The LCA is found at the point where the paths to
and
node_pdiverge, or at a point where one of the nodes is thenode_q.current_node
# Detailed Steps in Pseudocode
# Pseudocode with Comments
# Define the function to find the Lowest Common Ancestor in a BST
function FindLowestCommonAncestor(root, node_p, node_q):
# Start with the root of the tree
current_node = root
# Traverse the tree until we find the LCA or reach a null node
while current_node is not null:
# If both p and q are smaller than the current node's value, go left
if node_p.value < current_node.value and node_q.value < current_node.value:
current_node = current_node.left
# If both p and q are greater than the current node's value, go right
elif node_p.value > current_node.value and node_q.value > current_node.value:
current_node = current_node.right
# If p and q diverge or one of them equals the current node's value, return the current node as LCA
else:
return current_node
# If we exit the loop without finding the LCA, return null (though per constraints, this should not happen)
return null