Skip to main content

Lowest Common Ancestor of a Binary Tree

Problem Statement:​

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “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).”

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Example 3:

Input: root = [1,2], p = 1, q = 2
Output: 1
  • Example:



✅ Solution: Recursive DFS – Postorder Traversal​

class Solution {
public:
// Recursive function to find LCA of nodes p and q
TreeNode* lowestCommonAncestor(TreeNode* currentNode, TreeNode* p, TreeNode* q) {
// Base Case: found one of the nodes or reached the end
if(currentNode == NULL || currentNode == p || currentNode == q)
return currentNode;

// Recurse for left and right subtree
TreeNode* leftLCA = lowestCommonAncestor(currentNode->left, p, q);
TreeNode* rightLCA = lowestCommonAncestor(currentNode->right, p, q);

// If one node found in left and one in right, current is LCA
if(leftLCA != NULL && rightLCA != NULL)
return currentNode;

// Otherwise, return non-null value
return leftLCA != NULL ? leftLCA : rightLCA;
}
};


📝 How It Works​

  • This is a postorder traversal approach (left → right → root).
  • At each node, recursively check if p or q is found in the left and right subtree.
  • Three key base cases:
    • If current node is NULL, return NULL.
    • If current node is p or q, return that node.
  • If both left and right subtrees return non-null, it means:
    • One node was found in each subtree → current node is Lowest Common Ancestor (LCA).
  • If only one side returns non-null, that means both p and q lie in that subtree.

🧩 Key Logic​

if (left != NULL && right != NULL)
return root;
else
return left != NULL ? left : right;


⏱️ Time & Space Complexity​

MetricValue
TimeO(N) — visit each node once
SpaceO(H) — recursion stack (H = height of tree)

⚠️ Edge Cases​

  • p == q → returns p or q.
  • One node is the ancestor of the other.
  • Skewed trees (linked-list like) still work.
  • Tree is empty → returns NULL.

💡 Other Approaches​

ApproachTimeSpaceNotes
DFS Recursion ✅O(N)O(H)Clean and elegant
Path-based MethodO(N)O(N)Store paths to p and q, then compare

Path-based is helpful if the tree is not binary or is stored externally.



🚀 Level Up Your Engineering Mindset

Never Study in Isolation. Join Binary Dose.

Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.

Discord
Official Hub

Discord Community

Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.

Join Discord Server→
⚡
Daily Knowledge Drops

Daily Visual Deep-Dives

Bite-sized system design schematics, core OS internals, and DSA intuition served right into your feeds every single day.

💡Have handwritten notes, cheat-sheets, or want to publish a technical article?
Learn How to Contribute→