Reported January 2021
Bloombergtree

Lowest Common Ancestor in a Binary Tree

Reported by candidates from Bloomberg's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Bloomberg OA. Under 2s to a working solution.
Founder's read

Bloomberg reportedly served this lowest common ancestor question in January 2021, and the trap is hiding in Example 2. A node can be its own ancestor, so when p is an ancestor of q, the answer is p itself. Plenty of people write a version that only works when the two targets sit in different subtrees. It's a plain binary tree, not a BST, so you can't steer by comparing values. One recursive pass handles everything. If you freeze during the live OA, StealthCoder is the invisible safety net that reads the problem and hands you the working solution.

The problem

Given a binary tree and two distinct nodes in it, return the value of their lowest common ancestor. A node counts as a descendant of itself.
For this exercise, the runner supplies the target nodes by their unique integer values p and q, and returns the ancestor value instead of a node reference. Both targets exist in the tree. The tree is an ordinary binary tree, not necessarily a binary search tree.

Function
lowestCommonAncestorValue(root: TreeNode, p: int, q: int) → int

Examples
Example 1
root = [3,5,1,6,2,0,8,null,null,7,4]
p = 5
q = 1
return = 3
The first common ancestor is the root.
Example 2
root = [3,5,1,6,2,0,8,null,null,7,4]
p = 5
q = 4
return = 5
A node can be its own descendant, so 5 is the common ancestor.
Example 3
root = [1,2]
p = 1
q = 2
return = 1
The root is one of the requested nodes.

Constraints
The tree contains 2 through 100000 nodes.
-1000000000 <= node.val <= 1000000000; all node values are unique.
p != q and both target values occur in the tree.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The pattern is a post-order DFS. At each node, if it's null, or its value equals p or q, return it immediately. Otherwise recurse left and right. If both sides return non-null, the current node is the split point, so it's the answer. If only one side returns something, pass that up. That early return on a match is what covers the self-descendant case: when p sits above q, you return p and never need to look deeper. The common pitfall is searching for both nodes separately or assuming BST ordering. Another one is recursion depth. With up to 100000 nodes, a skewed tree can overflow the stack in some languages, so mention an iterative approach with parent pointers if asked. Time is O(n), space is O(h). If the recursion logic slips mid-assessment, StealthCoder is there as the hedge.

StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.

If this hits your live OA

You can drill Lowest Common Ancestor in a Binary Tree cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.

Get StealthCoder

Related leaked OAs

⏵ Practice the LeetCode equivalent

This OA pattern shows up on LeetCode as lowest common ancestor of a binary tree. If you have time before the OA, drill that.

⏵ The honest play

You've seen the question. Make sure you actually pass Bloomberg's OA.

Bloomberg reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Lowest Common Ancestor in a Binary Tree FAQ

What's the trick in the Bloomberg lowest common ancestor problem?+

Return the node as soon as it matches p or q, then combine results from the left and right subtrees. If both sides are non-null, the current node is the answer. The early return handles the case where one target is an ancestor of the other.

Can I use BST ordering to solve this?+

No. The problem says it's an ordinary binary tree, not necessarily a BST. Values aren't ordered, so comparing against the root tells you nothing. You have to search both subtrees with DFS and merge what comes back.

What edge case breaks a naive solution here?+

The case where p is an ancestor of q, like Example 2 with 5 and 4, or Example 3 with root 1 and child 2. A solution that demands the targets be in separate subtrees will miss it. Returning on first match fixes it.

Is recursion safe with 100000 nodes?+

It can be risky. A skewed tree gives a depth of 100000, which can overflow the call stack in some languages. If you're worried, build a parent map with an iterative traversal, then walk up from p and q until they meet.

How do I prepare for this in 48 hours?+

Write the recursive solution from memory three times and trace Examples 1 to 3 by hand. Then do the iterative parent-pointer version once. Know the complexity: O(n) time, O(h) space. That's enough for this question.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Bloomberg.

OA at Bloomberg?
Invisible during screen share
Get it