Smallest String Starting From Leaf
LeetCode 1030 | Difficulty: Mediumβ
MediumProblem Descriptionβ
You are given the root of a binary tree where each node has a value in the range [0, 25] representing the letters 'a' to 'z'.
Return the lexicographically smallest string that starts at a leaf of this tree and ends at the root.
As a reminder, any shorter prefix of a string is lexicographically smaller.
- For example, `"ab"` is lexicographically smaller than `"aba"`.
A leaf of a node is a node that has no children.
Example 1:

Input: root = [0,1,2,3,4,3,4]
Output: "dba"
Example 2:

Input: root = [25,1,3,1,3,0,2]
Output: "adz"
Example 3:

Input: root = [2,2,1,null,1,0,null,0]
Output: "abc"
Constraints:
- The number of nodes in the tree is in the range `[1, 8500]`.
- `0 <= Node.val <= 25`
Topics: String, Backtracking, Tree, Depth-First Search, Binary Tree
Approachβ
Backtrackingβ
Explore all candidates by building solutions incrementally. At each step, choose an option, explore further, then unchoose (backtrack) to try the next option. Prune branches that can't lead to valid solutions.
Generate all combinations/permutations, or find solutions that satisfy constraints.
Tree DFSβ
Traverse the tree recursively (or with a stack). At each node, decide: what information do I need from the left/right subtrees? Process: go left β go right β combine results. Consider preorder, inorder, or postorder traversal based on when you need to process the node.
Path problems, subtree properties, tree structure manipulation.
String Processingβ
Consider character frequency counts, two-pointer approaches, or building strings efficiently. For pattern matching, think about KMP or rolling hash. For palindromes, expand from center or use DP.
Anagram detection, palindrome checking, string transformation, pattern matching.
Solutionsβ
Solution 1: C# (Best: 237 ms)β
| Metric | Value |
|---|---|
| Runtime | 237 ms |
| Memory | 39.8 MB |
| Date | 2022-01-12 |
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
public class Solution {
public string SmallestFromLeaf(TreeNode root) {
if(root == null) return null;
return SmallestHelper(root, "");
}
public string SmallestHelper(TreeNode root, string suffix)
{
if(root == null) return suffix;
suffix = (char)(root.val+'a') + suffix;
if(root.left == null)
return SmallestHelper(root.right, suffix);
if(root.right == null)
return SmallestHelper(root.left, suffix);
string left = SmallestHelper(root.left, suffix);
string right = SmallestHelper(root.right, suffix);
if(left.CompareTo(right) < 0) return left;
else return right;
}
}
Complexity Analysisβ
| Approach | Time | Space |
|---|---|---|
| Backtracking | $O(n! or 2^n)$ | $O(n)$ |
| Tree Traversal | $O(n)$ | $O(h)$ |
Interview Tipsβ
- Discuss the brute force approach first, then optimize. Explain your thought process.
- Consider: "What information do I need from each subtree?" β this defines your recursive return value.
- Identify pruning conditions early to avoid exploring invalid branches.