Pattern #43

Postorder Traversal

Important interview questions, thinking patterns, Children-First (L-R-Root) processing, Global vs Return Value distinction, Tree DP, and Go code templates.

Must Solve

16 core questions — solve these first.

  1. 1.Binary Tree Postorder Traversal
    easy
  2. 2.Maximum Depth of Binary Tree
    easy
  3. 3.Diameter of Binary Tree
    easy
  4. 4.Balanced Binary Tree
    easy
  5. 5.Binary Tree Maximum Path Sum
    hard
  6. 6.House Robber III
    medium
  7. 7.Delete Leaves With a Given Value
    medium
  8. 8.Find Leaves of Binary Tree
    medium
  9. 9.Longest Univalue Path
    medium
  10. 10.Maximum Difference Between Node and Descendant Variants
    medium
  11. 11.Binary Tree Cameras
    hard
  12. 12.Lowest Common Ancestor of a Binary Tree
    medium
  13. 13.Subtree Sum Problems
    medium
  14. 14.Count Nodes / Subtree Size
    easy
  15. 15.Sum of Subtree
    easy
  16. 16.Tree DP Problems
    medium

Also Important

8 more questions worth practicing.

  1. 17.Minimum Depth of Binary Tree
    easy
  2. 18.Distribute Coins in Binary Tree
    medium
  3. 19.Smallest Subtree with All Deepest Nodes
    medium
  4. 20.Lowest Common Ancestor of Deepest Leaves
    medium
  5. 21.Maximum Product of Split Binary Tree
    medium
  6. 22.Delete Nodes and Return Forest
    medium
  7. 23.Tree Pruning
    medium
  8. 24.N-ary Tree Postorder Traversal
    easy

How to Think

  1. Parent needs child answers first?Postorder Traversal (Left -> Right -> Root)
  2. Need height / subtree size / sum?leftResult + rightResult + node.Val
  3. Need diameter / maximum path?Children return info + Parent updates global answer
  4. Need delete / prune based on children?Process children first, then decide parent

Go Postorder Code Templates

Recursive Postorder & Tree Height in Go

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// 1. Standard Postorder: Left -> Right -> Root
func postorderRecursive(root *TreeNode) []int {
    result := []int{}
    var dfs func(node *TreeNode)
    dfs = func(node *TreeNode) {
        if node == nil {
            return
        }
        dfs(node.Left)
        dfs(node.Right)
        result = append(result, node.Val) // Process Root Last!
    }
    dfs(root)
    return result
}

// 2. Postorder Tree Height Calculation
func treeHeight(root *TreeNode) int {
    if root == nil {
        return 0
    }
    leftHeight := treeHeight(root.Left)
    rightHeight := treeHeight(root.Right)

    return 1 + max(leftHeight, rightHeight)
}

👉 Total Time: O(N) | Space: O(H) stack

Global Candidate vs Return Value Distinction

In Postorder algorithms like Diameter or Max Path Sum, there is a key difference between what gets returned upward to the parent versus what updates the global answer:

// Binary Tree Maximum Path Sum
func maxPathSum(root *TreeNode) int {
    maxSum := -1 << 31

    var postorder func(node *TreeNode) int
    postorder = func(node *TreeNode) int {
        if node == nil {
            return 0
        }

        // 1. Get child branch gains (Drop negative gains!)
        leftGain := max(0, postorder(node.Left))
        rightGain := max(0, postorder(node.Right))

        // 2. Update Global Candidate Answer (Uses BOTH branches!)
        candidate := node.Val + leftGain + rightGain
        if candidate > maxSum {
            maxSum = candidate
        }

        // 3. Return Upward to Parent (MUST choose ONLY ONE branch!)
        return node.Val + max(leftGain, rightGain)
    }

    postorder(root)
    return maxSum
}

👉 Return value uses 1 branch; Global candidate evaluates both branches!

Bottom-Up Tree Pruning & Tree DP

1. Bottom-Up Deletion: Problems like Delete Leaves with Target Value require deleting children first. When a child gets removed, the parent may become a new leaf node and get deleted in turn!

2. Tree DP (House Robber III): Each node returns a state tuple [robCurrent, skipCurrent] back up to its parent based on its subtrees.

Visual Memory Rule
Postorder       → LEFT -> RIGHT -> ROOT (Children finish first, parent last)
Return Upward   → Return ONE branch height / gain to parent
Global Answer   → Update with BOTH branches
Tree DP         → Children return state tuple [rob, skip] to parent
Negative Branch → max(0, childGain) (Ignore harmful paths!)

💡 Golden Rule: "Let both children finish their work first, then use their answers to decide the parent."

Common Interview Mistakes

1. Processing Parent Too Early

Postorder parent MUST wait until both left and right children subtrees finish processing!

2. Mixing Return Value with Global Answer

In Diameter / Max Path Sum, do NOT return both branches upward! Return node.Val + max(left, right) while updating global max with node.Val + left + right.

3. Recalculating Child Info Repeatedly

Do not call a separate height/sum function inside a DFS loop causing O(N²)! Return all required subtree info in a single DFS traversal.

4. Using Preorder for Bottom-Up Decisions

If parent decision depends on modified child states (e.g. deleting leaves or camera placement), Preorder will fail! You MUST use Postorder.

Interview Rules

  1. 1. Parent needs child answers first? → Postorder Traversal
  2. 2. Traversal sequence?LEFT -> RIGHT -> ROOT
  3. 3. Height / Subtree Sum / Size?leftResult + rightResult + node.Val
  4. 4. Diameter / Max Path Sum? → Children return single-branch gain; Parent updates global answer with both branches
  5. 5. Negative child contribution? → Ignore it using max(0, childGain)
  6. 6. Tree DP (House Robber III / Cameras)? → Postorder returning state tuple to parent
  7. 7. Bottom-Up Pruning (Delete Leaves)? → Process children first, then evaluate parent
  8. 8. Overall Complexity → Time: O(N) | Stack Space: O(H) (O(log N) balanced, O(N) skewed)

Small Rules

  1. Rule 1: Postorder evaluates children first, parent last.
  2. Rule 2: Subtree information returns UPWARD from children to parent.
  3. Rule 3: Global candidate answer can use both branches, but return value upward uses only one branch.
  4. Rule 4: Tree DP algorithms rely almost exclusively on Postorder state returns.
  5. Rule 5: Bottom-up leaf deletion requires child subtrees to complete before evaluating parent node.

Production Thinking

Folder Size CalculationCalculating size of all files & subfolders before computing total parent folder size

Dependency Hierarchy CleanupSafely destroying child sub-resources before deleting parent resources

UI Component UnmountingExecuting child lifecycle cleanup before unmounting parent container

Expression Evaluation (Postfix)Evaluating operand child nodes first before performing operator calculation (2 + 3 * 4)

Remember This

Postorder       → LEFT -> RIGHT -> ROOT
Children        → First
Parent          → Last
Height          → Child heights then parent
Diameter        → Heights + global answer
Max Path        → Return one side, global uses both
Tree DP         → Postorder
Delete bottom-up→ Postorder
Subtree info    → Return UPWARD
Time            → O(N)

💡 Golden Rule: "Let both children finish their work first, then use their answers to decide the parent."