CMD Guide
HomeDSATrees

Introduction to Tree Depth First Search Pattern

Introduction to Tree Depth-First Search Pattern

Tree DFS solves problems by recursing into a node's children first and only combining their answers once both return — turning "what is true about this whole subtree" into "what is true about the current node, given what my children reported," which mirrors the tree's own recursive definition (a tree is a value plus two smaller trees).

Recognize the pattern

Brute force → optimal

Brute force: enumerate every root-to-leaf path explicitly (e.g., collect each path into a list as you DFS, sum it at the leaf, then scan all sums for the minimum). This does the same tree walk but pays extra memory to materialize every path — O(n) paths of average length O(log n) to O(n), so O(n log n) to O(n²) extra space/time just for storage.

Optimal: never materialize the paths. Fold the sum into the return value on the way back up — each node returns "the minimum leaf-path sum achievable from me downward," so the parent combines two numbers instead of two lists of paths.

Complexity from first principles

Each of the n nodes is visited exactly once, doing O(1) work (one comparison, one addition) per visit ⇒ O(n) time. There is no other traversal or repeated work, so this is tight — not a bound loosely covering something smaller.

Space: the recursion stack holds one frame per node on the current root-to-node path, so the stack depth equals the tree height h. That gives O(h) auxiliary space: O(log n) for a balanced tree, O(n) for a degenerate (linked-list-shaped) tree.

Worked example

Tree: root = [-1, 2, 3, 4, 5, 1] → -1 has children 2 and 3; 2 has children 4 and 5; 3 has right child 1.

CallLeaf?ReturnsReasoning
minSum(4)yes4leaf → return val
minSum(5)yes5leaf → return val
minSum(2)no2 + min(4,5) = 6combine children of 2
minSum(1)yes1leaf → return val
minSum(3)no (only right child)3 + 1 = 4left is null → use right only
minSum(-1)no-1 + min(6,4) = 3root combines 2's and 3's results

Final answer: 3, matching path -1 → 3 → 1.

Java implementation

class TreeNode {
    int val;
    TreeNode left, right;
    TreeNode(int val) { this.val = val; }
}

class Solution {
    public int minPathSum(TreeNode root) {
        if (root == null) return Integer.MAX_VALUE; // no path here
        if (root.left == null && root.right == null) return root.val; // leaf

        int leftSum = minPathSum(root.left);
        int rightSum = minPathSum(root.right);

        // if one child is missing, only the existing side is a valid path
        if (root.left == null) return root.val + rightSum;
        if (root.right == null) return root.val + leftSum;

        return root.val + Math.min(leftSum, rightSum);
    }
}

Pitfalls

When to use / when NOT — trade-offs

Use Tree DFS (post-order, bottom-up accumulation) whenever the answer at a node is a function of its subtrees' answers: height, diameter, path sums, subtree validation (e.g., BST check), lowest common ancestor. Avoid it when the problem is inherently level-based (shortest path in an unweighted tree/graph, level-order output, "nodes at distance k") — BFS is the named alternative there, since it explores level by level in O(n) time with O(w) space (w = max width), and guarantees minimum-depth answers first, which DFS cannot do without extra bookkeeping. DFS also loses to BFS when you need to short-circuit as soon as you hit the shallowest match.

Pre-order vs post-order — pick by data flow. If a node's answer needs information from above it (the running root-to-node sum, the current depth), carry that state down as a parameter on the way in — that is a pre-order (top-down) use. If a node's answer needs information from below it (subtree height, subtree sum, "is this a valid BST"), compute the children first and combine on the way back up — that is post-order (bottom-up). Height, diameter, and the classic binary-tree LCA are post-order; "path sum from the root" is top-down carry. LCA sketch (LeetCode 236): recurse; if the node is p or q, return it; if both the left and right recursive calls return non-null, this node is the LCA (p and q live in different subtrees); otherwise bubble up whichever side is non-null.

Vs. Morris traversal (O(1) auxiliary space): if even the O(h) recursion stack is unaffordable, Morris traversal threads temporary links from each node to its in-order predecessor and achieves O(1) extra space with O(n) time — but it temporarily mutates the tree, is far harder to write correctly, and is only worth it when memory is the hard constraint; the recursive O(h) DFS is the right default everywhere else.

Takeaways

Recall: Why is the space complexity of recursive Tree DFS O(h) rather than O(n), and when do these coincide?


Compiled from standard tree-DFS treatments (recursion-based subtree aggregation) and CS interview-prep pattern catalogs on tree path problems.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction to Tree Depth First Search Pattern? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction to Tree Depth First Search Pattern** (DSA) and want to truly understand it. Explain Introduction to Tree Depth First Search Pattern from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction to Tree Depth First Search Pattern** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction to Tree Depth First Search Pattern** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction to Tree Depth First Search Pattern** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes