Given the root of a binary tree, return the values of its boundary in anti-clockwise order, starting from the root.
The boundary is the concatenation of: the root; the left boundary (top-down, excluding leaves); the leaves (left to right); and the right boundary (bottom-up, excluding leaves). The left boundary is the path from the root's left child taking left when possible else right; the right boundary is symmetric. Each node appears once, and if the root is a leaf the boundary is just the root.
The tree is given in level-order (breadth-first), using null for missing children.
Input: root = [1, null, 2, 3, 4] Output: [1, 3, 4, 2] Root 1; no non-leaf left boundary; leaves 3, 4; right boundary (2) bottom-up.
Input: root = [1, 2, 3, 4, 5, 6, null, null, null, 7, 8, 9, 10] Output: [1, 2, 4, 7, 8, 9, 10, 6, 3] Root; left boundary 2; leaves 4, 7, 8, 9, 10; right boundary 6, 3 bottom-up.
- The number of nodes is in the range [1, 10^4] - -1000 <= Node.val <= 1000
The boundary is four pieces glued together: root, left boundary (top-down), leaves (left to right), and right boundary (bottom-up). The care is in avoiding duplicates — the left and right boundaries exclude leaves (which the leaf pass covers) — and in reversing the right boundary so the whole thing reads anti-clockwise.
“Order?”
Anti-clockwise: root, left side down, leaves left-to-right, right side up.
“Are leaves counted twice?”
No — the side boundaries exclude leaves; leaves are listed once in the leaf pass.
I output the root, then the left boundary top-down excluding leaves, then all leaves left to right, then the right boundary bottom-up excluding leaves.
The two side passes skip leaves to avoid double-counting, and the right side is reversed so the traversal is anti-clockwise.
Worked example — tree [1, 2, 3, 4, 5, 6, null, null, null, 7, 8, 9, 10]
root: 1 left boundary (from 2, skip leaves): 2 leaves (L->R): 4, 7, 8, 9, 10 right boundary (from 3, skip leaves), reversed: 6, 3 boundary: [1, 2, 4, 7, 8, 9, 10, 6, 3]
Root, left (top-down), leaves (L-R), right (bottom-up) — the anti-clockwise loop.
Leaves belong only to the leaf pass; skip them in the side boundaries to avoid duplicates.
Collected top-down, it must be reversed to complete the anti-clockwise order.
| Iterative side passes | Recursive side passes | |
|---|---|---|
| Idea | While-loops for left/right, DFS for leaves | Pre-order left, post-order right, DFS leaves |
| Time | O(n) | O(n) |
| Space | O(n) | O(height) |
Same four-part decomposition; the recursion appends the right boundary post-order to get bottom-up for free. Full code is in the Approaches selector below.
Key takeaway
Concatenate root + left boundary (top-down, no leaves) + leaves (L→R) + right boundary (bottom-up, no leaves). Exclude leaves from the sides and reverse the right side. O(n).
res = [root] walk left edge (skip leaves) top-down collect all leaves left to right walk right edge (skip leaves), reverse, append