Problem Description
Given the root of a binary tree, the task is to return the boundary of the tree as a list of node values. The boundary is defined as the concatenation of:
- The root node.
- The left boundary (excluding leaves and the root).
- All the leaf nodes from left to right.
- The right boundary (excluding leaves and the root) in reverse order.
The left boundary is obtained by starting from the root's left child and repeatedly moving to the left if possible (or to the right if a left child is not available), excluding the leaf nodes. Similarly, the right boundary is obtained from the root’s right child with the analogous criteria.
Key Insights
- Break down the problem into three parts:
- Left boundary (excluding leaves).
- All leaves (do a DFS to find leaves).
- Right boundary (excluding leaves, then reverse the collected list).
- Special handling is needed when the tree doesn't have a left or right subtree.
- The root is always included and is never considered as a leaf, even if it has no children.
- Avoid duplication of leaf nodes in the left/right boundaries.
Space and Time Complexity
Time Complexity: O(n) – Every node is visited at most once. Space Complexity: O(n) – O(n) space is used for the output list and recursion stack (in worst case tree is skewed).
Solution
The solution uses a Depth-First Search (DFS) strategy to traverse the tree and collect the boundary nodes in three steps:
- For the left boundary, start at root.left and traverse down, adding nodes (skipping leaves).
- For the leaves, perform a DFS from the root and add any node that has no children.
- For the right boundary, start at root.right and traverse down, adding nodes (skipping leaves). Since the right boundary must be added in reverse order, we reverse the collected list after traversal.
- Finally, concatenate these lists in the order: root, left boundary, leaves, reversed right boundary.
The approach makes use of helper functions to clearly separate the logic for gathering left boundary, leaves, and right boundary. This modular approach simplifies reasoning and avoids edge case mistakes such as including duplicate leaf nodes.