LeetCode #145 Easy

Binary Tree Postorder Traversal

Given the root of a binary tree, return the postorder traversal of its node values: left subtree, right subtree, and the node itself last.

binary treedfsrecursion
Open on LeetCode ↗
02

Intuition

Postorder visits a node only after both subtrees are finished — children first, parent last. It's the order you'd delete a tree safely, or compute anything where a node's answer depends on its children's answers.

How to spot this pattern

Children before node — the order for anything where a parent's answer depends on its subtrees' answers: deleting a tree, computing heights, evaluating an expression tree. If the node needs results from below, postorder is the traversal.

03

Approach

1

Visit after both children

Move the append below the two recursive calls: recurse left, recurse right, then record node.val. The node waits until everything beneath it is done — the root is always the very last value in the output.

2

The 'answers flow upward' order

Postorder is the shape of almost every tree DP: size of subtree, height, 'is balanced', evaluating an expression tree. Whenever a parent needs its children's results first, you're writing postorder whether you call it that or not.

3

Iterative trick

Do a modified preorder (node, right, left) with a stack and reverse the result at the end — far simpler than tracking whether each node's children are done.

04

Solution & live demo

1class Solution:
2 def postorderTraversal(self, root):
3 res = []
4 def dfs(node):
5 if not node:
6 return
7 dfs(node.left)
8 dfs(node.right)
9 res.append(node.val)
10 dfs(root)
11 return res
05

Common pitfalls

Reversing preorder without swapping the child order

✗ Wrong
preorder(root)[::-1]
✓ Right
dfs(node.left)
dfs(node.right)
res.append(node.val)

Reversed preorder is node-right-left reversed, which equals left-right-node only if you also swapped the children during the preorder. The trick works, but only as reversed root-right-left — plain reversed preorder is wrong.

Appending the value between the two recursive calls

✗ Wrong
dfs(node.left)
res.append(node.val)
dfs(node.right)
✓ Right
dfs(node.left)
dfs(node.right)
res.append(node.val)

That's inorder. The defining property of postorder is that a node appears only after everything beneath it, which requires both calls to complete first.

Using it where the parent must act first

✗ Wrong
# postorder to propagate a value downward
✓ Right
# preorder for top-down, postorder for bottom-up

Information flowing from root to leaves needs the parent processed first. Postorder gives the parent its children's results, which is the opposite direction — picking the wrong one makes the state at each node unavailable when needed.

06

Edge cases

Empty tree

Base case → empty list.

Root with two leaves

Output is left leaf, right leaf, root — parent strictly after children.

Deep skewed tree

Recursion unwinds from the bottom, so the deepest node is emitted first and the root last.

07

Complexity

Time
O(n)
Space
O(h)
Each node once; stack holds one root-to-leaf path.