Tree Depth-First Search Pattern
Tree DFS explores a tree by going as deep as possible along one branch before backtracking, traditionally implemented through recursion or an explicit stack. It is the workhorse pattern for path problems, subtree aggregates, validation checks, and any computation whose answer depends on root-to-leaf information, running in O(n) time and O(h) space where h is tree height.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Complexity
- Time
- O(n)
- Space
- O(h)
When to use Tree Depth-First Search
- The problem asks about root-to-leaf paths, longest path, or any path-sum target.
- You need to compute a value at every subtree (size, height, max, sum) and combine it with the parent's value.
- You need to validate a tree property (is BST, is balanced, is symmetric) that requires checking left and right subtrees.
- You need to serialize, deserialize, or compare two trees structurally.
- Pre-order, in-order, or post-order traversal yields the answer directly (BSTs and in-order are a classic pair).
Template
function pathSum(root, target) {
if (root === null) return false;
function dfs(node, remaining) {
if (node === null) return false;
if (node.left === null && node.right === null) {
return remaining === node.val;
}
return dfs(node.left, remaining - node.val)
|| dfs(node.right, remaining - node.val);
}
return dfs(root, target);
}Example LeetCode problems
| # | Problem | Difficulty | Frequency |
|---|---|---|---|
| 104 | Maximum Depth of Binary Tree | easy | foundational |
| 112 | Path Sum | easy | foundational |
| 113 | Path Sum II | medium | frequently asked |
| 124 | Binary Tree Maximum Path Sum | hard | company favorite |
| 98 | Validate Binary Search Tree | medium | company favorite |
| 543 | Diameter of Binary Tree | easy | frequently asked |
| 236 | Lowest Common Ancestor of a Binary Tree | medium | company favorite |
| 101 | Symmetric Tree | easy | foundational |
| 226 | Invert Binary Tree | easy | classic |
Common mistakes
- Treating a single null child as a leaf, which is wrong for path-sum problems — a leaf has BOTH children null.
- Validating a BST by checking only the immediate child instead of carrying down a min/max range; this misses cross-subtree violations.
- Forgetting to remove a node from the running path when backtracking in path-collection problems, which produces stale paths.
- Returning early from `dfs` before visiting both subtrees when the problem requires aggregating both results.
- Using global mutable state for the answer instead of returning values up the call stack, which breaks when the function recurses on multiple inputs.
Frequently asked questions
Which traversal order should I use: pre-order, in-order, or post-order?
Pre-order (root first) suits top-down problems where the parent's value passes information down. In-order (left, root, right) yields sorted output for BSTs. Post-order (children first) suits bottom-up aggregates where you need both subtree results before computing the node's value.
Should I write DFS recursively or iteratively with a stack?
Recursion is the canonical interview answer for tree DFS — it is shorter, clearer, and matches the structure of the problem. Switch to an explicit stack only if the interviewer asks about deep trees that would overflow the call stack.
What is the space complexity of recursive DFS?
O(h) where h is the height of the tree, because the call stack holds one frame per ancestor. For balanced trees that's O(log n); for skewed trees it can degrade to O(n).
How does DFS handle Lowest Common Ancestor problems?
Recurse into left and right subtrees and return the node itself when you find a target. The lowest ancestor is the first node whose recursion returns non-null from BOTH subtrees, which propagates upward as the answer.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
Practice these live with InterviewChamp.AI
Drill the Tree Depth-First Search pattern under real interview conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →