236. Lowest Common Ancestor of a Binary Tree
mediumAsked at Juniper NetworksFind the lowest common ancestor of two nodes in a binary tree using recursive post-order traversal. Juniper applies this to hierarchical network configuration trees — finding the most-specific policy node that governs both a source and destination interface requires exactly this LCA traversal.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Juniper Networks loops.
- Glassdoor (2025-Q3)— Cited in Juniper SWE onsite reports as a tree traversal problem with hierarchical reasoning context.
- Blind (2025-08)— Juniper candidates list LCA as a medium tree problem that appears in networking software roles.
Problem
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA: 'The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).'
Constraints
The number of nodes in the tree is in the range [2, 10^5].−10^9 <= Node.val <= 10^9All Node.val are unique.p != qBoth p and q will exist in the tree.
Examples
Example 1
root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 13Explanation: LCA of nodes 5 and 1 is 3.
Example 2
root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 45Explanation: LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself.
Approaches
1. Recursive post-order DFS
Post-order recursion: search left and right subtrees. If a node is p or q, return it. If both children return non-null, the current node is the LCA. If only one returns non-null, propagate that result upward.
- Time
- O(n)
- Space
- O(h) call stack, h = tree height
function lowestCommonAncestor(root, p, q) {
if (root === null) return null;
if (root === p || root === q) return root; // found one of the targets
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
if (left !== null && right !== null) return root; // p in left, q in right
return left !== null ? left : right; // propagate the found node upward
}Tradeoff: O(n) time, O(h) space. Elegant single-pass post-order traversal. The insight is that returning a node indicates 'p or q (or their LCA) is in this subtree.'
Juniper Networks-specific tips
Walk through the recursion logic carefully — Juniper interviewers will trace through an example. The key insight to articulate is: 'If I find p in the left subtree and q in the right subtree (or vice versa), the current node must be the LCA. If I find both in the same subtree, propagate the LCA upward from that subtree.' Mention the special case: a node can be the LCA of itself and its descendant — handled by the root === p || root === q early return.
Common mistakes
- Not handling the case where a node is the ancestor of itself — the early return (root === p || root === q) must come before recursing into children.
- Assuming the tree is a BST and using the BST LCA shortcut — this tree is a general binary tree, not a BST.
- Recursing into children even after finding p — the early return prevents unnecessary traversal.
- Checking node values instead of node references — the problem guarantees unique values but reference comparison is safer and more direct.
Follow-up questions
An interviewer at Juniper Networks may pivot to one of these next:
- LCA of a Binary Search Tree (LC 235) — simpler because BST ordering allows a guided search.
- LCA with parent pointers (LC 1650) — two-pointer approach using path lengths.
- How would you find the most-specific policy node governing two interfaces in a hierarchical Junos configuration?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
What does returning root mean when both left and right are non-null?
It means p was found in one subtree and q in the other. The current node is the split point — and therefore the LCA.
What if one of the targets is an ancestor of the other?
The early return (root === p || root === q) fires first, returning the ancestor before recursing further. The ancestor is correctly identified as the LCA.
Is this approach valid for a general binary tree (not a BST)?
Yes — it does a full post-order traversal of the entire tree without relying on any ordering property.
Practice these live with InterviewChamp.AI
Drill Lowest Common Ancestor of a Binary Tree and other Juniper Networks interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →