Given the root of a binary tree, return the postorder traversal of its nodes' values — visit the left subtree, then the right subtree, then the node last.
The tree is given in level-order (breadth-first), using null for missing children.
lastVisited pointer: only pop and record a node once its right child has been visited, otherwise descend right first.Input: root = [1, null, 2, 3] Output: [3, 2, 1] Left subtree (empty), then the right subtree yielding 3 then 2, then the root 1 last.
Input: root = [] Output: [] An empty tree has no nodes.
- The number of nodes is in the range [0, 100] - -100 <= Node.val <= 100
Postorder means left, right, node — a node is recorded only after both its subtrees are done. The recursive version is a direct transcription. The neat iterative trick: do a modified preorder that visits node, right, left, then reverse the whole thing — the reverse of (node, right, left) is exactly (left, right, node).
“What is postorder exactly?”
The left subtree, then the right subtree, then the current node.
“Why is postorder useful?”
Anything that needs child results before the parent — deleting a tree, computing height, path sums.
Postorder is left, right, node, so I recurse into both subtrees before recording the node.
Iteratively I run a node-right-left walk with a stack and reverse the result — that reversal turns it into left-right-node.
Worked example — tree [1, null, 2, 3] (1 with right child 2, whose left child is 3)
1
\
2
/
3
postorder: left of 1 (none) -> right subtree of 1 -> 1
in that subtree: 3 -> 2
result: [3, 2, 1]
The node comes last, after both subtrees — which is why it's the order for bottom-up computations.
A stack-based node-right-left walk, reversed, is postorder — the cleanest iterative version.
Every node is visited once (O(n)); the stack holds at most O(height) nodes.
| Iterative (reversed node-right-left) | Recursive | |
|---|---|---|
| Idea | Walk node-right-left with a stack, reverse | dfs(left); dfs(right); record |
| Time | O(n) | O(n) |
| Space | O(n) | O(height) |
Both are O(n) time; the recursive form is the clearest. Full code is in the Approaches selector below.
Key takeaway
Postorder = left, right, node. Recurse both subtrees before recording the node — or run a node-right-left stack walk and reverse it. O(n) time, O(height) space recursively.
postorder(node):
if node is null: return
postorder(node.left)
postorder(node.right)
visit(node)