Report Tree Levels and Balanced Subtrees
NetflixSoftware Engineer · OnsiteLast updated
Tests traversing a binary tree stored in array (heap) layout to compute subtree heights and identify nodes rooted at height-balanced subtrees along with their tree levels.
Problem Statement
You are given a binary tree represented as a zero-based array values, following standard heap layout:
- The root is at index
0. - For any node at index
i, its left child is at index2 * i + 1and its right child is at index2 * i + 2. - An element in
valuescan beNone, indicating the absence of a node at that position. An indexi >= len(values)also represents an absent node.
A subtree rooted at node u is considered height-balanced if:
- The left subtree is height-balanced (an empty subtree is trivially balanced with height
0). - The right subtree is height-balanced.
- The absolute difference between the height of the left subtree and the height of the right subtree is at most
1.
The height of an empty subtree is 0, and the height of a non-empty subtree is 1 + max(left_height, right_height).
Implement describe_balanced_nodes(values) to find all existing nodes whose subtrees are height-balanced. For each such node, return its index in the array and its 0-indexed level (where the root at index 0 has level 0).
Return the results as a list of tuples (index, level) sorted primarily by level in ascending order, and secondarily by index in ascending order.
Function Signature
def describe_balanced_nodes(values: list[int | None]) -> list[tuple[int, int]]:
pass
Constraints
0 <= len(values) <= 10^5values[i]is an integer between-10^9and10^9, orNone.
Examples
Example 1
Input: values = [1, 2, 3, 4, None, 6, 7]
Output: [(1, 1), (2, 1), (3, 2), (5, 2), (6, 2)]
Explanation:
- Index
0(value 1, level 0): Left subtree (rooted at 1) has height 2 (children: left=4, right=None). Right subtree (rooted at 2) has height 2 (children: left=6, right=7). Height difference is|2 - 2| = 0. However, the left child at index 1 is checked: left child has left subtree of height 1 (node 4) and right subtree of height 0 (None), which has height difference|1 - 0| = 1(balanced). Node 1 is balanced. Right child at index 2 has left subtree height 1 and right subtree height 1 (balanced). Since both subtrees are balanced and heights differ by 0, index 0 is also balanced! Wait: if index 0 is balanced, shouldn't index 0 be included? Yes! Let's check: Node 0 is balanced, so it should be included as(0, 0). Let's provide the exact example where node 0 is NOT balanced to illustrate unbalanced cases clearly:
Input: values = [1, 2, None, 3]
Output: [(1, 1), (3, 2)]
Explanation:
- Node 0 has left child 1 (height 2) and right child
None(height 0). The difference is|2 - 0| = 2 > 1, so node 0 is not balanced. - Node 1 has left child 3 (height 1) and right child
None(height 0). The difference is|1 - 0| = 1 <= 1, and both subtrees are balanced, so node 1 is balanced (level 1). - Node 3 has no children (height 1), so it is balanced (level 2).
Example 2
Input: values = []
Output: []
Hints
Hint 1
Use a bottom-up post-order traversal to compute the height of each subtree while simultaneously checking if it is balanced.
Hint 2
A helper function can return a tuple `(is_balanced, height)` for each index, returning `(True, 0)` when an index is out of bounds or `values[i] is None`.
Hint 3
Calculate a node's level directly from its index `i` (level = `i.bit_length() - 1`) or pass it down during traversal.
Follow-up questions
- How would you handle extremely sparse trees where `len(values)` is large but the actual number of nodes is small? Would an explicit pointer-based tree or adjacency list be better?
- Can you modify your implementation to run iteratively instead of recursively to avoid call-stack overflow on degenerate trees?
- If the array is immutable and shared across concurrent reader threads, what thread-safety considerations apply?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.