Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Lowest Common Ancestor of Deepest Leaves in Pytho
In a rooted binary tree, we need to find the lowest common ancestor (LCA) of the deepest leaves. The deepest leaves are the leaf nodes that are furthest from the root.
Key concepts:
A leaf node has no children
The depth of the root is 0, and each child's depth is parent's depth + 1
The LCA is the deepest node that contains all target nodes in its subtree
Algorithm
We use a recursive approach that returns both the depth and the LCA node:
If a node is null, return depth 0 and None
If a node is a leaf, return depth 1 and the node itself
Recursively find depths and LCAs for left and right subtrees
If left depth > right depth, return left result with incremented depth
If right depth > left depth, return right result with incremented depth
If depths are equal, the current node is the LCA
Example
Let's implement the solution with a complete example ?
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def insert(temp, data):
que = []
que.append(temp)
while len(que):
temp = que[0]
que.pop(0)
if not temp.left:
if data is not None:
temp.left = TreeNode(data)
else:
temp.left = TreeNode(0)
break
else:
que.append(temp.left)
if not temp.right:
if data is not None:
temp.right = TreeNode(data)
else:
temp.right = TreeNode(0)
break
else:
que.append(temp.right)
def make_tree(elements):
tree = TreeNode(elements[0])
for element in elements[1:]:
insert(tree, element)
return tree
def print_tree(root):
# Print using inorder traversal
if root is not None:
print_tree(root.left)
print(root.data, end=', ')
print_tree(root.right)
class Solution:
def lcaDeepestLeaves(self, root):
return self.solve(root)[1]
def solve(self, node):
if not node:
return [0, None]
if not node.left and not node.right:
return [1, node]
d1, l = self.solve(node.left)
d2, r = self.solve(node.right)
if d1 > d2:
return [d1 + 1, l]
elif d2 > d1:
return [d2 + 1, r]
return [d1 + 1, node]
# Test the solution
ob = Solution()
root = make_tree([1, 2, 3, 4, 5])
result = ob.lcaDeepestLeaves(root)
print("LCA of deepest leaves:")
print_tree(result)
The output shows the inorder traversal of the subtree rooted at the LCA ?
LCA of deepest leaves: 4, 2, 5,
How It Works
For the tree [1, 2, 3, 4, 5]:
Node 4 and 5 are at depth 2 (deepest leaves)
Node 2 is their lowest common ancestor
The algorithm returns node 2, whose subtree contains nodes 4, 2, and 5
Time Complexity
The time complexity is O(n) where n is the number of nodes, as we visit each node once. The space complexity is O(h) where h is the height of the tree due to recursion.
Conclusion
This recursive solution efficiently finds the LCA of deepest leaves by tracking depths and comparing subtrees. The key insight is that when left and right subtrees have equal maximum depths, the current node becomes the LCA.
