LeetCode ยท #236

Lowest Common Ancestor of a Binary Tree Solution

Use post-order DFS to detect where the search paths for p and q first meet.

01
Section One ยท Problem

Problem Statement

๐Ÿท๏ธ

Difficulty

Medium

๐Ÿ”—

LeetCode

Problem #236

๐Ÿ—๏ธ

Pattern

Tree DFS โ€” post-order merge

Given the root of a binary tree and two nodes p and q, return their lowest common ancestor โ€” the deepest node that has both as descendants, where a node can be a descendant of itself.

Example
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3
02
Section Two ยท Brute Force

Store Parent Pointers

Traverse once to record each node's parent, then walk upward from one node while marking ancestors, and finally climb from the other until you hit a marked one.

Problem: This works, but it needs extra hash maps/sets. A recursive DFS can solve the problem directly with the tree structure alone.
03
Section Three ยท Optimal

Recursive DFS โ€” O(n)

At each node, ask the left and right subtrees whether they contain p or q.

๐Ÿ’ก Mental model: Imagine searching for two people in a building. If one is found in the left wing and the other in the right wing, the current hallway intersection is their first common meeting point โ€” the LCA.
Core logic
  • If the current node is null, return null.
  • If the current node equals p or q, return it.
  • Recurse into left and right.
  • If both sides return non-null, current node is the LCA.
  • Otherwise return whichever side is non-null.
Why this works: The first node where the search results come back from both sides is exactly the deepest split point between p and q.
04
Section Four ยท Trace

Visual Walkthrough

When both recursive calls succeed, current node is the answer
Example: p = 5, q = 1 At node 3: search left subtree โ†’ finds 5 At node 3: search right subtree โ†’ finds 1 Both sides are non-null, so node 3 is the LCA If both targets were on the same side, the answer would bubble up from that subtree instead. Answer: node 3 โœ“
05
Section Five ยท Implementation

Code โ€” Java & Python

Java โ€” post-order DFS
class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if (left != null && right != null) return root; return left != null ? left : right; } }
Python โ€” post-order DFS
class Solution: def lowestCommonAncestor(self, root, p, q): if not root or root == p or root == q: return root left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) if left and right: return root return left if left else right
06
Section Six ยท Analysis

Complexity Analysis

ApproachTimeSpace
Parent map + ancestor setO(n)O(n)
Recursive DFSO(n)O(h)
07
Section Seven ยท Edge Cases

Edge Cases & Pitfalls

CaseWhy it matters
One node is ancestor of the otherThat ancestor is the LCA, and the base case handles it naturally.
Targets on different sides of rootThe root becomes the answer.
Skewed treeStill correct, but recursion depth becomes O(n).
โš  Common Mistake: Assuming LCA works like the BST version. In a general binary tree, there is no ordering rule like โ€œgo left if both are smaller.โ€ You must search both subtrees.

โ† Back to Trees problems