Binary Tree Postorder Traversal

EasyTrees · Post-order Traversal🧩 Tree DFSLeetCode #145 ↗Updated

Problem

Given the root of a binary tree, return its node values in post-order: for every node, all of its left subtree first, then all of its right subtree, and only then the node itself. An empty tree gives an empty list.
Inputroot = [1,null,2,3]Output[3,2,1]
Inputroot = [1,2,3,4,5]Output[4,5,2,3,1]
Inputroot = []Output[]

0 ≤ n ≤ 100  ·  -100 ≤ Node.val ≤ 100  ·  Follow-up: recursion is trivial — can you do it iteratively?

Try it yourself

Java
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
A node may be emitted only after both children are finished. When you are back at a node, the question is “did I come from the left or the right?” — track the last visited node to tell.
PatternTree DFS

Instinct If the answer for a node can be built from the answers of its left and right subtrees, write one recursive function and trust it on the children.

Memory hack Ask the kids, then decide - each child reports up, the parent combines, and a global variable keeps the best "bend" seen so far.

Open the Tree DFS guide →

Approaches

Brute ForceRecursive DFS

Time O(n)Space O(h)

Follow the definition: recurse left, recurse right, then add the node. Each node is visited once; the call stack grows to the tree height h (n when the tree is a chain).

Java
public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> res = new ArrayList<>();
    dfs(root, res);
    return res;
}

private void dfs(TreeNode node, List<Integer> res) {
    if (node == null) return;
    dfs(node.left, res);
    dfs(node.right, res);
    res.add(node.val);
}

Trivial and correct, but deep trees can overflow the call stack.

At a glance

LevelApproachTimeSpace
Brute ForceRecursive DFSO(n)O(h)
BetterOne Stack + Last-Visited PointerO(n)O(h)
OptimalMorris Post-order (Reverse Right Edges)O(n)O(1)
Common pitfalls
  • Popping as soon as the left spine ends — that emits in-order, not post-order.
  • Without last, the loop re-enters the right subtree forever.
  • Morris: not removing the thread before walking the right edge — loops back to curr.
Interview tips
  • Explain why post-order is the hardest iterative traversal: the node is seen twice.
  • Offer the reverse-pre-order trick as a quick alternative, then the one-stack version.
  • Mention post-order's use: freeing trees, subtree sums/heights, bottom-up DP.
Pattern
Post-order (children before parent) → bottom-up tree computations like height, diameter, subtree sums.
My notes saved in this browser