Interview question
Flatten a category tree to paths
Flattens a tree into display paths while preserving order and preventing simple cycles.
TL;DR
Flattens a tree into display paths while preserving order and preventing simple cycles.
Recursion, tree traversal, path state, cycle defense, ordering, and practical DTO shaping.
Practice the problem like a real interview: restate, reason, implement, and test.
Implement FlattenPaths(Category root) returning every node path in depth-first order. Each path joins names with /. Child order is the order given. Protect against cycles by throwing if the same node id appears twice in the current path.
Next in Coding Practice: Paged Result Helper
Tree: Books -> Programming -> C#
Output: Books, Books / Programming, Books / Programming / C#
InvalidOperationException.I would use a recursive DFS with a path list and a set of ids currently in the path. When I enter a node, I add its id to the active set and its name to the path, emit the joined path, then visit children. On exit, I remove both. The active set catches cycles without blocking the same id in a different branch unless the domain says ids must be globally unique.
public sealed record Category(string Id, string Name, IReadOnlyList<Category> Children);
public static IReadOnlyList<string> FlattenPaths(Category? root)
{
if (root is null)
{
return Array.Empty<string>();
}
var result = new List<string>();
var path = new List<string>();
var activeIds = new HashSet<string>(StringComparer.Ordinal);
void Visit(Category node)
{
if (!activeIds.Add(node.Id))
{
throw new InvalidOperationException($"Cycle detected at category '{node.Id}'.");
}
path.Add(node.Name);
result.Add(string.Join(" / ", path));
foreach (var child in node.Children ?? Array.Empty<Category>())
{
Visit(child);
}
path.RemoveAt(path.Count - 1);
activeIds.Remove(node.Id);
}
Visit(root);
return result;
}
The traversal is O(n * p) if joining the path costs p per node. Space is O(d) for recursion depth and current path, plus O(n) for output.
Spot a weak answer, missing edge case, or clearer explanation? Send it in.