Quick Overview

A binary tree coding problem: given a tree in level-order form, add up the values of the nodes on its boundary, meaning the root, the left edge, the leaves and the right edge, each counted once. It tests precise traversal rules, careful edge definitions and correct handling of skewed and single-node trees.

Sum of the Node Values on a Binary Tree's Boundary

Company: Snowflake

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: Technical Screen

Picture walking around the outside of a binary tree, starting at the root: you go down the left edge, along the leaves at the bottom from left to right, and back up the right edge. The nodes you pass form the tree's boundary. Given a binary tree of integers, return the sum of the values of its boundary nodes. Each node counts at most once. ### Function Signature ```python def boundary_sum(tree: list[int | None]) -> int: ``` `tree` is the tree in level order, and `tree[0]` is the root. Nodes receive their children in the order they appear in the list: the root takes the next two entries as its left child and right child, then the next present node in the list takes the following two entries, and so on. `None` means that the child is absent, and a `None` entry takes no entries of its own. If the list ends early, the remaining children are absent. ### Rules - The root is on the boundary. The root is never treated as a leaf, even when it has no children. - A leaf is any node other than the root that has no children. Every leaf is on the boundary. - The left edge starts at the root's left child; if the root has no left child, the left edge is empty. From a node on the left edge that is not a leaf, the edge continues to that node's left child if it has one, and otherwise to its right child. The walk stops when it reaches a leaf, which is counted as a leaf and not again as part of the left edge. - The right edge is the mirror image: it starts at the root's right child (it is empty if there is none) and continues to a node's right child if it has one, and otherwise to its left child, stopping at a leaf. - Every node that is not the root, a leaf, or on one of the two edges is interior and is not counted. - Return the sum of the values of the root, the left-edge nodes, the leaves and the right-edge nodes. ### Constraints - `1 <= number of nodes <= 10^4`, and `tree[0]` is not `None`. - `len(tree) <= 2 * 10^4 + 1` - `-1000 <= node value <= 1000` - The tree may be completely skewed, so its height can equal the number of nodes. - The absolute value of the answer is at most `10^7`, so it fits in a signed 32-bit integer. ### Examples **Example 1** ```text Input: tree = [1, 2, 3, 4, 5, 6, None, None, None, 7, 8, 9, 10] Output: 50 ``` The root 1 has children 2 and 3. Node 2 has children 4 and 5, and node 3 has only a left child, 6. Node 4 is a leaf, node 5 has children 7 and 8, and node 6 has children 9 and 10. The left edge is just 2, because its left child 4 is a leaf. The leaves from left to right are 4, 7, 8, 9 and 10. The right edge is 3 and then 6, because 3 has no right child; the walk stops at 6's right child 10, which is a leaf. Node 5 is interior. The sum is 1 + 2 + 4 + 7 + 8 + 9 + 10 + 6 + 3 = 50. **Example 2** ```text Input: tree = [1, None, 2, 3, 4, 5, 6] Output: 18 ``` The root 1 has only a right child, 2. Node 2 has children 3 and 4, and node 3 has children 5 and 6. Because the root has no left child, the left edge is empty, so node 3 is not on it. The leaves are 5, 6 and 4, and the right edge is just 2, because its right child 4 is a leaf. Node 3 is interior. The sum is 1 + 5 + 6 + 4 + 2 = 18. **Example 3** ```text Input: tree = [-7] Output: -7 ``` A single node is the root. It is not a leaf, so it is counted exactly once.

Overview: A binary tree coding problem: given a tree in level-order form, add up the values of the nodes on its boundary, meaning the root, the left edge, the leaves and the right edge, each counted once. It tests precise traversal rules, careful edge definitions and correct handling of skewed and single-node trees.

Read the full Snowflake Software Engineer interview experience this question came from

Picture walking around the outside of a binary tree, starting at the root: you go down the left edge, along the leaves at the bottom from left to right, and back up the right edge. The nodes you pass form the tree's boundary. Given a binary tree of integers, return the sum of the values of its boundary nodes. Each node counts at most once. **Input format** `tree` is the tree in level order, and `tree[0]` is the root. Nodes receive their children in the order they appear in the list: the root takes the next two entries as its left child and right child, then the next present node in the list takes the following two entries, and so on. `None` means that the child is absent, and a `None` entry takes no entries of its own. If the list ends early, the remaining children are absent. The list is a valid level-order encoding, so every non-`None` entry is a node of the tree. An absent entry is `None` in Python, `null` in JavaScript and in the Java `java.util.List<Integer>`, and an empty `std::optional<int>` in C++. **Rules** - The root is on the boundary. The root is never treated as a leaf, even when it has no children. - A leaf is any node other than the root that has no children. Every leaf is on the boundary. - The left edge starts at the root's left child; if the root has no left child, the left edge is empty. From a node on the left edge that is not a leaf, the edge continues to that node's left child if it has one, and otherwise to its right child. The walk stops when it reaches a leaf, which is counted as a leaf and not again as part of the left edge. - The right edge is the mirror image: it starts at the root's right child (it is empty if there is none) and continues to a node's right child if it has one, and otherwise to its left child, stopping at a leaf. - Every node that is not the root, a leaf, or on one of the two edges is interior and is not counted. - Return the sum of the values of the root, the left-edge nodes, the leaves and the right-edge nodes. **Example 1** ``` Input: tree = [1, 2, 3, 4, 5, 6, None, None, None, 7, 8, 9, 10] Output: 50 ``` The root 1 has children 2 and 3. Node 2 has children 4 and 5, and node 3 has only a left child, 6. Node 4 is a leaf, node 5 has children 7 and 8, and node 6 has children 9 and 10. The left edge is just 2, because its left child 4 is a leaf. The leaves from left to right are 4, 7, 8, 9 and 10. The right edge is 3 and then 6, because 3 has no right child; the walk stops at 6's right child 10, which is a leaf. Node 5 is interior. The sum is 1 + 2 + 4 + 7 + 8 + 9 + 10 + 6 + 3 = 50. **Example 2** ``` Input: tree = [1, None, 2, 3, 4, 5, 6] Output: 18 ``` The root 1 has only a right child, 2. Node 2 has children 3 and 4, and node 3 has children 5 and 6. Because the root has no left child, the left edge is empty, so node 3 is not on it. The leaves are 5, 6 and 4, and the right edge is just 2, because its right child 4 is a leaf. Node 3 is interior. The sum is 1 + 5 + 6 + 4 + 2 = 18. **Constraints** - `1 <= number of nodes <= 10^4`, and `tree[0]` is not `None`. - `len(tree) <= 2 * 10^4 + 1` - `-1000 <= node value <= 1000` - The tree may be completely skewed, so its height can equal the number of nodes. - The absolute value of the answer is at most `10^7`, so it fits in a signed 32-bit integer: it never exceeds 2^31 - 1, and `int` is enough in Java and C++.

Constraints

  • 1 <= number of nodes <= 10^4, and tree[0] is not None.
  • len(tree) <= 2 * 10^4 + 1
  • -1000 <= node value <= 1000
  • The tree may be completely skewed, so its height can equal the number of nodes.
  • The absolute value of the answer is at most 10^7, so it fits in a signed 32-bit integer.

Examples

Input: ([1, 2, 3, 4, 5, 6, None, None, None, 7, 8, 9, 10],)

Expected Output: 50

Explanation: Source Example 1: left edge 2, leaves 4, 7, 8, 9, 10, right edge 3 then 6 (falls through to the left child); node 5 is interior. 1+2+4+7+8+9+10+6+3 = 50.

Input: ([1, None, 2, 3, 4, 5, 6],)

Expected Output: 18

Explanation: Source Example 2: the root has no left child, so the left edge is empty and node 3 is interior; 1+5+6+4+2 = 18.

Hints

  1. Rebuild the child links first: only present nodes claim entries, they claim them two at a time in the order they appear in the list, and a None entry claims nothing.
  2. Whether a non-root node is a leaf depends only on its own children, so the leaves can be identified without knowing where the two edges run.
  3. The tree can be 10^4 levels deep, so make sure any walk over it does not rely on deep recursion.

Loading coding console...

Show the approach

Approach

Rebuild the child links with one left-to-right scan. Present nodes are numbered in the order they are created, which is exactly the order in which they claim list entries, so an index head over the created nodes plays the role of the level-order queue: node head takes the next entry as its left child and the one after it as its right child, a None entry creates nothing, and the scan stops when the list runs out (remaining children are absent). Then add (1) the root, (2) every non-root node with no children, which are the leaves, (3) each non-leaf node met while walking the left edge from the root's left child, stepping to the left child when present and otherwise to the right child, and (4) the mirror walk for the right edge from the root's right child. Correctness: both walks stop on the first leaf they reach, so they add only non-leaf nodes, and a leaf is added only in step 2; the left walk stays inside the root's left subtree and the right walk inside its right subtree, so no node is on both edges; the root is excluded from step 2 and from both walks. Hence every boundary node is added exactly once and every interior node is never added. Edge cases: a lone root is counted once and is not a leaf; a root with a single child has an empty edge on the missing side, so nodes on that side of the remaining subtree can be interior; a list that ends early leaves the remaining children absent; trailing None entries add nothing. Every step is iterative, so a fully skewed tree of height 10^4 needs no recursion. The answer is at most 10^7 in absolute value, so 32-bit integers suffice.

Time complexity:
O(n)
Space complexity:
O(n)