Boundary of Binary Tree
Return the anticlockwise boundary: root, left edge (top-down), all leaves (left-to-right), right edge (bottom-up) — no duplicates.
Open on LeetCode ↗Intuition
The boundary is three separate walks stitched together: slide down the left spine, collect leaves with a normal DFS, slide down the right spine but emit it reversed. The finicky part is exclusion — spine nodes that are leaves belong to the leaf pass only, and the root is emitted once up front.
Three disjoint pieces stitched together: left spine top-down, all leaves left-to-right, right spine bottom-up. The is_leaf exclusion in both spine walks is what stops nodes being counted twice, since a spine can end in a leaf that the middle pass will also collect.
Approach
Three collectors
leftBoundary: follow left (else right) from root.left, skipping leaves. leaves: DFS all. rightBoundary: follow right (else left) from root.right, skipping leaves, then reverse.
Dedup by role
Root printed first (unless it's a leaf, then the leaf pass owns it); spine passes skip leaves; leaf pass skips nothing — every boundary node has exactly one owner.
Stitch
[root] + left + leaves + reversed(right).
Solution & live demo
Common pitfalls
Including leaves while walking the spines
while cur:
res.append(cur.val)
cur = cur.left if cur.left else cur.rightwhile cur:
if not is_leaf(cur): res.append(cur.val)
cur = ...The leaf pass collects every leaf, including the ones terminating each spine. Without the exclusion those nodes appear twice in the output.
Following only the left child down the left spine
cur = cur.left
cur = cur.left if cur.left else cur.right
The left boundary continues through a right child when no left child exists — the spine is the leftmost path, not the chain of left pointers. Stopping early truncates the boundary.
Not special-casing a single-node tree
res = [root.val] # then spine and leaf passes
if is_leaf(root): return [root.val]
A lone root is itself a leaf, so the leaf pass adds it a second time. The guard returns before the three-part assembly can duplicate it.
Edge cases
Missing spine contributes nothing; leaves and the existing spine still cover the outline.
Root is a leaf → emit once, not twice.