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
Smallest String Starting From Leaf in Python
Suppose we have the root of a binary tree, where each node contains a value from 0 to 25, representing the letters 'a' to 'z': a value of 0 represents 'a', a value of 1 represents 'b', and so on. We have to find the lexicographically smallest string that starts at a leaf of this tree and ends at the root.
For the tree shown above, the output will be "adz" as the sequence from leaf to root is [0,3,25].
Algorithm
To solve this problem, we use Depth-First Search (DFS) to traverse all paths from root to leaf, then reverse each path to get leaf-to-root strings ?
Perform DFS traversal from root to all leaves
For each leaf node, construct the string from leaf to root
Keep track of the lexicographically smallest string found
Use backtracking to explore all possible paths
Implementation
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def insert(temp, data):
queue = [temp]
while queue:
temp = queue.pop(0)
if not temp.left:
temp.left = TreeNode(data) if data is not None else TreeNode(0)
break
else:
queue.append(temp.left)
if not temp.right:
temp.right = TreeNode(data) if data is not None else TreeNode(0)
break
else:
queue.append(temp.right)
def make_tree(elements):
if not elements:
return None
tree = TreeNode(elements[0])
for element in elements[1:]:
insert(tree, element)
return tree
class Solution:
def smallestFromLeaf(self, root):
self.ans = "~" # Initialize with largest possible character
self.dfs(root, [])
return self.ans
def dfs(self, node, path):
if node:
# Add current node's character to path
path.append(chr(node.data + ord('a')))
# If it's a leaf node, compare the reversed path
if not node.left and not node.right:
current_string = ''.join(reversed(path))
self.ans = min(self.ans, current_string)
path.pop()
return
# Recursively traverse left and right subtrees
self.dfs(node.left, path)
self.dfs(node.right, path)
# Backtrack: remove current node from path
path.pop()
# Create the tree and test
root = make_tree([25, 1, 3, 1, 3, 0, 2])
solution = Solution()
result = solution.smallestFromLeaf(root)
print(f"Smallest string from leaf: {result}")
Smallest string from leaf: adz
How It Works
The algorithm works by maintaining a path from root to the current node during DFS traversal. When we reach a leaf node, we reverse this path to get the string from leaf to root and compare it with our current answer.
Step-by-Step Process
# Let's trace through the algorithm with a simple example
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
# Create a simple tree: root(2) with left(0) and right(1)
root = TreeNode(2) # 'c'
root.left = TreeNode(0) # 'a'
root.right = TreeNode(1) # 'b'
def trace_paths(node, path, paths):
if node:
path.append(chr(node.data + ord('a')))
if not node.left and not node.right:
# Leaf node - record the path from leaf to root
leaf_to_root = ''.join(reversed(path))
paths.append(leaf_to_root)
print(f"Leaf path: {' -> '.join(path)} = {leaf_to_root}")
trace_paths(node.left, path, paths)
trace_paths(node.right, path, paths)
path.pop()
paths = []
trace_paths(root, [], paths)
print(f"All paths: {paths}")
print(f"Smallest: {min(paths)}")
Leaf path: c -> a = ac Leaf path: c -> b = bc All paths: ['ac', 'bc'] Smallest: ac
Key Points
Time Complexity: O(N) where N is the number of nodes, as we visit each node once
Space Complexity: O(H) where H is the height of the tree for the recursion stack
Backtracking: Essential to explore all paths without interference
String Comparison: Python's lexicographical comparison works perfectly for finding the minimum
Conclusion
This solution uses DFS with backtracking to find all leaf-to-root paths, then returns the lexicographically smallest one. The key insight is reversing the root-to-leaf path to get the required leaf-to-root string for comparison.
