Coding Software Engineer Reported Apr, 2026 High Frequency
You receive an organizational hierarchy as a list[list[str]].
Every nested list follows this layout:
[manager, report_1, report_2,...]
For instance:
[
["R", "S", "T"],
["S", "V"],
["T", "U"],
]
represents the following relationships:
R is the manager of S and TS is the manager of VT is the manager of UThe resulting reporting layout is:
R
....S
........V
....T
........U
This question generally contains three core stages, although certain interviewers include a fourth extension.
Assume all of the following:
....)Construct the organization tree, then display the complete hierarchy using the indentation style shown earlier.
relations = [
["R", "S", "T"],
["S", "V"],
["T", "U"],
]
Output:
R
....S
........V
....T
........U
Create a children adjacency mapping, identify the root employee, and render the tree with DFS.
from collections import defaultdict
def build_children(relations: list[list[str]]) -> tuple[dict[str, list[str]], str]:
children: dict[str, list[str]] = defaultdict(list)
parent: dict[str, str] = {}
people = set()
for relation in relations:
manager, *reports = relation
people.add(manager)
children[manager]
for report in reports:
people.add(report)
children[manager].append(report)
children[report]
parent[report] = manager
roots = [name for name in people if name not in parent]
if len(roots) != 1:
raise ValueError("Expected exactly one root")
return children, roots[0]
def render_full_chain(relations: list[list[str]]) -> str:
children, root = build_children(relations)
Output: list[str] = []
def visit(name: str, level: int) -> None:
output.append(f"{'....' * level}{name}")
for report in children[name]:
visit(report, level + 1)
visit(root, 0)
return "\n".join(output)
A manager who oversees other managers may want meetings with people precisely two reporting layers beneath them.
Return every valid (manager, employee) pair at that skip level.
Using the same hierarchy:
R can bypass S and meet with VR can bypass T and meet with UYou may use any suitable return representation, provided that it contains the correct pairs.
[("R", "V"), ("R", "U")]
After building the hierarchy, each required pair is simply a manager together with one of that manager's grandchildren.
def all_skip_level_pairs(relations: list[list[str]]) -> list[tuple[str, str]]:
children, root = build_children(relations)
result: list[tuple[str, str]] = []
def visit(name: str) -> None:
for report in children[name]:
for indirect_report in children[report]:
result.append((name, indirect_report))
visit(report)
visit(root)
return result
For a specified employee, print both of these portions:
Use the same indentation convention as in Part 1.
For target S, given:
relations = [
["R", "S", "T"],
["S", "V"],
["T", "U"],
]
the result is:
R
....S
........V
When the target is T, the result becomes:
R
....T
........U
This stage is often the one candidates find most difficult. It requires both of these pieces:
A straightforward approach stores a parent mapping, which lets you rebuild the upward route before rendering the target's lower hierarchy.
The important point is that the target must be printed only one time:
from collections import defaultdict
def build_graph(
relations: list[list[str]],
) -> tuple[dict[str, list[str]], dict[str, str], str]:
children: dict[str, list[str]] = defaultdict(list)
parent: dict[str, str] = {}
people = set()
for relation in relations:
manager, *reports = relation
people.add(manager)
children[manager]
for report in reports:
people.add(report)
children[manager].append(report)
children[report]
parent[report] = manager
roots = [name for name in people if name not in parent]
if len(roots) != 1:
raise ValueError("Expected exactly one root")
return children, parent, roots[0]
def render_chain_for(relations: list[list[str]], target: str) -> str:
children, parent, _root = build_graph(relations)
if target not in children:
raise ValueError(f"Unknown employee: {target}")
path = [target]
name = target
while name in parent:
name = parent[name]
path.append(name)
path.reverse()
Output: list[str] = []
for level, name in enumerate(path):
output.append(f"{'....' * level}{name}")
def visit_subtree(name: str, level: int) -> None:
output.append(f"{'....' * level}{name}")
for report in children[name]:
visit_subtree(report, level + 1)
for report in children[target]:
visit_subtree(report, len(path))
return "\n".join(output)
Some interviewers continue with this extension:
For two employees, determine their lowest shared manager.
For the same hierarchy:
lowest_common_manager("T", "V") == "R"
Because the parent mapping is already available, the lowest-common-manager extension is direct to implement:
def lowest_common_manager(
relations: list[list[str]], employee1: str, employee2: str
) -> str:
children, parent, _root = build_graph(relations)
if employee1 not in children or employee2 not in children:
raise ValueError("Unknown employee")
ancestor_names = set()
name = employee1
ancestor_names.add(name)
while name in parent:
name = parent[name]
ancestor_names.add(name)
name = employee2
while name not in ancestor_names:
name = parent[name]
return name
If additional extensions keep arriving, it is usually preferable to consolidate the behavior in a reusable OrgChart class.
from collections import defaultdict
class OrgChart:
INDENT = "...."
def __init__(self, relations: list[list[str]]):
self.children: dict[str, list[str]] = defaultdict(list)
self.parent: dict[str, str] = {}
self._appearance_order: list[str] = []
seen = set()
for row in relations:
if not row:
continue
manager, *reports = row
self._remember(manager, seen)
self.children[manager]
for report in reports:
self._remember(report, seen)
self.children[manager].append(report)
self.children[report]
self.parent[report] = manager
roots = [name for name in self._appearance_order if name not in self.parent]
if len(roots) != 1:
raise ValueError("Input must contain exactly one root")
self.root = roots[0]
def _remember(self, name: str, seen: set[str]) -> None:
if name not in seen:
seen.add(name)
self._appearance_order.append(name)
def render_full_chain(self) -> str:
lines: list[str] = []
self._render_subtree(self.root, 0, lines)
return "\n".join(lines)
def all_skip_level_pairs(self) -> list[tuple[str, str]]:
pairs: list[tuple[str, str]] = []
def dfs(node: str) -> None:
for child in self.children[node]:
for grandchild in self.children[child]:
pairs.append((node, grandchild))
dfs(child)
dfs(self.root)
return pairs
def render_chain_for(self, target: str) -> str:
if target not in self.children:
raise ValueError(f"Unknown employee: {target}")
path = self._path_from_root(target)
lines: list[str] = []
for depth, name in enumerate(path):
lines.append(f"{self.INDENT * depth}{name}")
target_depth = len(path) - 1
for child in self.children[target]:
self._render_subtree(child, target_depth + 1, lines)
return "\n".join(lines)
def lowest_common_manager(self, employee1: str, employee2: str) -> str:
if employee1 not in self.children or employee2 not in self.children:
raise ValueError("Unknown employee")
ancestors = set()
current = employee1
ancestors.add(current)
while current in self.parent:
current = self.parent[current]
ancestors.add(current)
current = employee2
while current not in ancestors:
current = self.parent[current]
return current
def _path_from_root(self, target: str) -> list[str]:
path = [target]
current = target
while current in self.parent:
current = self.parent[current]
path.append(current)
path.reverse()
return path
def _render_subtree(self, node: str, depth: int, lines: list[str]) -> None:
lines.append(f"{self.INDENT * depth}{node}")
for child in self.children[node]:
self._render_subtree(child, depth + 1, lines)
relations = [
["R", "S", "T"],
["S", "V"],
["T", "U"],
]
chart = OrgChart(relations)
print(chart.render_full_chain())
# R
#....S
#........V
#....T
#........U
print(chart.all_skip_level_pairs())
# [('R', 'V'), ('R', 'U')]
print(chart.render_chain_for("S"))
# R
#....S
#........V
print(chart.lowest_common_manager("T", "V"))
# R
Let n denote the employee count.
O(n)O(n)O(n)O(h + s)
h is the root-to-target heights is the number of nodes in the target's subtreeO(h)O(n)def render_full_chain(relations: list[list[str]]) -> str:
pass