Bird
Raised Fist0
DSA Javascriptprogramming

Lowest Common Ancestor in Binary Tree in DSA Javascript

Choose your learning style10 modes available
Mental Model
Find the closest shared parent node of two given nodes in a tree by checking where their paths meet.
Analogy: Imagine a family tree where you want to find the closest common grandparent of two cousins by tracing their parents upwards until you find the same person.
      1
     / \
    2   3
   / \   \
  4   5   6
Dry Run Walkthrough
Input: Binary tree: 1->2->4, 2->5, 1->3->6; find LCA of nodes 4 and 5
Goal: Find the lowest node that is an ancestor of both 4 and 5
Step 1: Start at root node 1, check left and right subtrees for nodes 4 and 5
At node 1: searching left subtree -> 2, right subtree -> 3
Why: We need to explore both sides to find nodes 4 and 5
Step 2: At node 2, check left child 4 and right child 5
At node 2: left child 4 found, right child 5 found
Why: Both nodes found in different subtrees of 2, so 2 is common ancestor
Step 3: Return node 2 as LCA since both nodes found in its subtrees
LCA found: node 2
Why: Lowest node with both nodes in its subtrees is the answer
Result:
2
Annotated Code
DSA Javascript
class TreeNode {
  constructor(val) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}

function lowestCommonAncestor(root, p, q) {
  if (root === null) return null;
  if (root === p || root === q) return root;

  const left = lowestCommonAncestor(root.left, p, q);
  const right = lowestCommonAncestor(root.right, p, q);

  if (left !== null && right !== null) return root;
  return left !== null ? left : right;
}

// Build tree
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);

const p = root.left.left;  // Node 4
const q = root.left.right; // Node 5

const lca = lowestCommonAncestor(root, p, q);
console.log(lca.val);
if (root === null) return null;
stop if reached empty subtree
if (root === p || root === q) return root;
return current node if it matches one of the targets
const left = lowestCommonAncestor(root.left, p, q);
search left subtree for targets
const right = lowestCommonAncestor(root.right, p, q);
search right subtree for targets
if (left !== null && right !== null) return root;
if targets found in both subtrees, current node is LCA
return left !== null ? left : right;
otherwise return non-null subtree result
OutputSuccess
2
Complexity Analysis
Time: O(n) because we visit each node once in the worst case
Space: O(h) where h is tree height due to recursion stack
vs Alternative: Compared to storing paths for both nodes and comparing, this approach uses less space and is simpler
Edge Cases
One or both nodes not present in tree
Function returns null if either node is missing
DSA Javascript
if (root === null) return null;
One node is ancestor of the other
Ancestor node is returned as LCA
DSA Javascript
if (root === p || root === q) return root;
Tree with only one node which is both p and q
That node is returned as LCA
DSA Javascript
if (root === p || root === q) return root;
When to Use This Pattern
When asked to find the closest shared parent of two nodes in a tree, use the Lowest Common Ancestor pattern because it efficiently finds the meeting point of their paths.
Common Mistakes
Mistake: Returning immediately after finding one node without checking the other subtree
Fix: Always search both left and right subtrees before deciding the LCA
Mistake: Not handling the case when one node is ancestor of the other
Fix: Return current node if it matches either target node
Summary
Finds the lowest node that is an ancestor of two given nodes in a binary tree.
Use when you need to find the closest shared parent node of two nodes in a tree.
The key insight is that if one node is found in the left subtree and the other in the right, the current node is their lowest common ancestor.

Practice

(1/5)
1. What is the Lowest Common Ancestor (LCA) of two nodes in a binary tree?
easy
A. The node that appears first in an inorder traversal
B. The root node of the binary tree
C. The deepest node that is an ancestor of both nodes
D. The node with the smallest value between the two nodes

Solution

  1. Step 1: Understand ancestor concept

    An ancestor of a node is any node on the path from the root to that node.
  2. Step 2: Define lowest common ancestor

    The lowest common ancestor is the deepest node that is an ancestor of both given nodes.
  3. Final Answer:

    The deepest node that is an ancestor of both nodes -> Option C
  4. Quick Check:

    LCA = deepest common ancestor [OK]
Hint: LCA is the deepest shared parent node [OK]
Common Mistakes:
  • Confusing LCA with root node
  • Choosing node with smallest value
  • Selecting node based on traversal order
2. Which of the following is the correct base case condition in a recursive function to find LCA in a binary tree?
easy
A. if (root.right == null) return root;
B. if (root.left == null) return root;
C. if (root.value == null) return root;
D. if (root == null) return null;

Solution

  1. Step 1: Identify base case for recursion

    When the current node is null, it means we've reached the end of a path without finding the target nodes.
  2. Step 2: Correct base case condition

    Return null to indicate no ancestor found in this path.
  3. Final Answer:

    if (root == null) return null; -> Option D
  4. Quick Check:

    Base case returns null on null node [OK]
Hint: Return null when node is null [OK]
Common Mistakes:
  • Returning root when left or right child is null
  • Checking root.value == null which is invalid
  • Missing base case leading to infinite recursion
3. Consider the following binary tree and code snippet to find LCA of nodes 5 and 1:
    3
   / \
  5   1
 / \ / \
6  2 0  8

function findLCA(root, p, q) {
  if (!root || root === p || root === q) return root;
  const left = findLCA(root.left, p, q);
  const right = findLCA(root.right, p, q);
  if (left && right) return root;
  return left ? left : right;
}

const lca = findLCA(root, node5, node1);
console.log(lca.value);
What will be printed?
medium
A. 5
B. 3
C. 1
D. null

Solution

  1. Step 1: Trace recursive calls for nodes 5 and 1

    Both nodes 5 and 1 are children of root 3, so recursion finds them in left and right subtrees respectively.
  2. Step 2: Determine LCA based on recursion

    Since left and right recursive calls return non-null (nodes 5 and 1), the current root 3 is the LCA.
  3. Final Answer:

    3 -> Option B
  4. Quick Check:

    LCA of 5 and 1 is 3 [OK]
Hint: If both sides return nodes, root is LCA [OK]
Common Mistakes:
  • Returning one of the nodes instead of root
  • Confusing node values with LCA
  • Ignoring both left and right recursive results
4. The following code attempts to find the LCA but has a bug. What is the error?
function findLCA(root, p, q) {
  if (!root) return null;
  if (root === p || root === q) return root;
  const left = findLCA(root.left, p, q);
  const right = findLCA(root.right, p, q);
  if (left) return left;
  if (right) return right;
  return null;
}
medium
A. It returns left child even if right child is also non-null
B. It does not check if root is null
C. It returns root instead of null when no nodes found
D. It does not handle the case when p or q is missing

Solution

  1. Step 1: Analyze return conditions after recursion

    The code returns left if left is non-null without checking right, missing the case when both are non-null.
  2. Step 2: Identify missing combined check

    It should return root if both left and right are non-null, indicating LCA found at current root.
  3. Final Answer:

    It returns left child even if right child is also non-null -> Option A
  4. Quick Check:

    Must check both sides before returning [OK]
Hint: Check both left and right before returning root [OK]
Common Mistakes:
  • Returning left without checking right
  • Missing combined condition for LCA
  • Ignoring null root check
5. Given a binary tree where nodes 2 and 4 are in the left subtree of node 3, and nodes 5 and 6 are in the right subtree of node 3, what is the LCA of nodes 2 and 6?
hard
A. 3
B. 2
C. 4
D. 5

Solution

  1. Step 1: Understand tree structure

    Nodes 2 and 4 are in left subtree of 3; nodes 5 and 6 are in right subtree of 3.
  2. Step 2: Find common ancestor of nodes 2 and 6

    Since 2 is in left subtree and 6 is in right subtree, their lowest common ancestor is the root node 3.
  3. Final Answer:

    3 -> Option A
  4. Quick Check:

    LCA of nodes in opposite subtrees is root [OK]
Hint: LCA of nodes in different subtrees is their root [OK]
Common Mistakes:
  • Choosing one of the nodes instead of ancestor
  • Confusing sibling nodes as LCA
  • Ignoring tree structure
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard