I am trying to implement the solution to the problem Lowest Common Ancestor(LCA) of Binary Tree via top-down recursion.
The approach I have used is:
IDEA: Find the node which has one of the desired nodes in either subtree while the other desired node is the opposite subtree.
PSEUDOCODE 1. If the value of root is equal to either of the desired node's value, the root is the LCA. 2. Search in the left subtree for either node. 3. Search in the right subtree for either node. 4. If neither of them contains any of the two nodes, the nodes do not exist in the tree rooted at the root node. 5. If each of them contains one node, the root is the LCA. 6. If either one of them contains a node, return it to the root.
This is what has also been recommended in answers of related questions on StackOverflow.
Now, this code works well if we assume all the nodes of the tree to be of unique value. In other words, this approach seems to break in case of duplicates (or, is it just my implementation?)
I would like to know how can I fix my code to work with duplicate values as well. If this approach cannot result in the optimal solution, how should I alter my approach?
Here is the exact implementation:
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def __repr__(self):
return 'TreeNode({}, {}, {})'.format(self.val, self.left, self.right)
def lowestCommonAncestor(root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if root is None:
return None
if p.val == root.val or q.val == root.val:
return root
left_subtree = lowestCommonAncestor(root.left, p, q)
right_subtree = lowestCommonAncestor(root.right, p, q)
if left_subtree is None and right_subtree is None:
return None
if left_subtree is not None and right_subtree is not None:
return root
if left_subtree is None:
return right_subtree
else:
return left_subtree
For example:
root = TreeNode(2)
root.left = TreeNode(3)
root.left.left = TreeNode(1)
root.right = TreeNode(5)
root.right.left = TreeNode(7)
root.right.right = TreeNode(1)
print(lowestCommonAncestor(root, TreeNode(1), TreeNode(7)))
This returns the root of the tree as the result. result = TreeNode(2)
No doubt, the root is always an ancestor.
However, there exists a "lower" common ancestor than the root - TreeNode(5)
.