Filter Matching Subtrees from an N-Ary Tree
Company: Waymo
Role: Frontend Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
# Filter Matching Subtrees from an N-Ary Tree
Remove every node whose string value contains a given substring. Removing a node also removes its entire descendant subtree, even if some descendants would not match on their own.
The original interview report describes the tree behavior but not its exact data model. Use the following flat, literal representation as the practice contract.
```python
def filter_nary_tree(
nodes: list[list[object]],
forbidden: str,
) -> list[list[object]]:
...
```
Each element of `nodes` is `[value, child_indices]`, where `value` is a string and `child_indices` is a list of integer indices in display order. When `nodes` is nonempty, index `0` is the root, every other node has exactly one parent, and the input forms one valid acyclic tree.
Return the surviving tree in the same representation, compactly reindexed in preorder. Preserve the relative order of surviving children. If the root is removed, return `[]`.
## Matching Rules
- Matching is case-sensitive and uses ordinary substring containment.
- An empty `forbidden` string matches every value, so the result is `[]` for a nonempty tree.
- Do not mutate the input.
## Example
```text
Input:
nodes = [
["root", [1, 2, 3]],
["keep-a", []],
["remove-me", [4, 5]],
["keep-b", [6]],
["hidden-a", []],
["hidden-b", []],
["keep-c", []]
]
forbidden = "remove"
Output:
[
["root", [1, 2]],
["keep-a", []],
["keep-b", [3]],
["keep-c", []]
]
```
Nodes 4 and 5 disappear because their parent matches, even though their own values do not.
## Constraints and Errors
- `0 <= len(nodes) <= 200_000`
- The total number of child indices is at most `len(nodes) - 1`.
- Values and `forbidden` contain at most 1,000 Unicode code points each.
- A malformed record, non-string value or `forbidden`, non-list child list, out-of-range child index, repeated parent, cycle, disconnected non-root node, or Boolean used as an index must raise `ValueError`.
- Validate the complete input before returning a result.
## Hints
- A matching node can be rejected before visiting its descendants.
- Build a new preorder result and assign each surviving node its new index when it is appended.
- An iterative traversal avoids recursion-depth failures on a highly skewed tree.
Quick Answer: Filter an n-ary tree by removing every node whose value contains a substring along with its full descendant subtree. Validate the flat index representation, preserve child order, reindex survivors in preorder, and avoid recursion limits on deep trees.
Validate a flat indexed N-ary tree, remove every node whose string value contains a forbidden substring together with its descendants, and return the survivors compactly reindexed in preorder with child order preserved.
Constraints
- The input may contain 200,000 nodes.
- Every non-root node has exactly one parent and the graph is one acyclic tree.
- Matching is case-sensitive substring containment.
- An empty forbidden string removes every nonempty tree.
Examples
Input: {'nodes':[['root',[1,2,3]],['keep-a',[]],['remove-me',[4,5]],['keep-b',[6]],['hidden-a',[]],['hidden-b',[]],['keep-c',[]]],'forbidden':'remove'}
Expected Output: [['root', [1, 2]], ['keep-a', []], ['keep-b', [3]], ['keep-c', []]]
Explanation: The supplied example prunes one entire middle subtree.
Input: {'nodes':[],'forbidden':'x'}
Expected Output: []
Explanation: An empty tree remains empty.
Hints
- Validate all records and parent counts before filtering.
- Use an explicit preorder stack and push children in reverse display order.
- Assign each output index at append time.