Bird
Raised Fist0
DSA Typescriptprogramming~20 mins

Lowest Common Ancestor in Binary Tree in DSA Typescript - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
LCA Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of LCA for given nodes in a binary tree
What is the output of the following TypeScript code that finds the Lowest Common Ancestor (LCA) of nodes 5 and 1 in the binary tree?
DSA Typescript
class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
    this.val = val === undefined ? 0 : val;
    this.left = left === undefined ? null : left;
    this.right = right === undefined ? null : right;
  }
}

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

// Construct the tree
const root = new TreeNode(3);
root.left = new TreeNode(5);
root.right = new TreeNode(1);
root.left.left = new TreeNode(6);
root.left.right = new TreeNode(2);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(8);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(4);

const p = root.left; // Node with val 5
const q = root.right; // Node with val 1

const ancestor = lowestCommonAncestor(root, p, q);
console.log(ancestor ? ancestor.val : null);
Anull
B5
C1
D3
Attempts:
2 left
💡 Hint
Think about where nodes 5 and 1 meet first when traversing from the root.
❓ Predict Output
intermediate
2:00remaining
Output of LCA for nodes in same subtree
What is the output of the following TypeScript code that finds the Lowest Common Ancestor (LCA) of nodes 7 and 4 in the binary tree?
DSA Typescript
class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
    this.val = val === undefined ? 0 : val;
    this.left = left === undefined ? null : left;
    this.right = right === undefined ? null : right;
  }
}

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

// Construct the tree
const root = new TreeNode(3);
root.left = new TreeNode(5);
root.right = new TreeNode(1);
root.left.left = new TreeNode(6);
root.left.right = new TreeNode(2);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(8);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(4);

const p = root.left.right.left; // Node with val 7
const q = root.left.right.right; // Node with val 4

const ancestor = lowestCommonAncestor(root, p, q);
console.log(ancestor ? ancestor.val : null);
A5
B2
C3
D7
Attempts:
2 left
💡 Hint
Both nodes are in the right subtree of node 5.
🔧 Debug
advanced
2:00remaining
Identify the error in LCA function
What error will the following TypeScript code produce when trying to find the LCA of nodes 5 and 1?
DSA Typescript
class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
    this.val = val === undefined ? 0 : val;
    this.left = left === undefined ? null : left;
    this.right = right === undefined ? null : right;
  }
}

function lowestCommonAncestor(root: TreeNode | null, p: TreeNode, q: TreeNode): TreeNode | null {
  if (!root) return null;
  if (root.val === p.val) return root;
  if (root.val === q.val) return root;
  const left = lowestCommonAncestor(root.left, p, q);
  const right = lowestCommonAncestor(root.right, p, q);
  if (left && right) return root;
  return left || right;
}

// Construct the tree
const root = new TreeNode(3);
root.left = new TreeNode(5);
root.right = new TreeNode(1);
root.left.left = new TreeNode(6);
root.left.right = new TreeNode(2);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(8);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(4);

const p = root.left; // Node with val 5
const q = root.right; // Node with val 1

const ancestor = lowestCommonAncestor(root, p, q);
console.log(ancestor ? ancestor.val : null);
ANo error, outputs 3
BTypeError: Cannot read property 'val' of null
COutputs null
DStack overflow due to infinite recursion
Attempts:
2 left
💡 Hint
Check how the function compares nodes using val property.
❓ Predict Output
advanced
2:00remaining
Output when one node is ancestor of the other
What is the output of the following TypeScript code that finds the Lowest Common Ancestor (LCA) of nodes 5 and 4, where 5 is an ancestor of 4?
DSA Typescript
class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
    this.val = val === undefined ? 0 : val;
    this.left = left === undefined ? null : left;
    this.right = right === undefined ? null : right;
  }
}

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

// Construct the tree
const root = new TreeNode(3);
root.left = new TreeNode(5);
root.right = new TreeNode(1);
root.left.left = new TreeNode(6);
root.left.right = new TreeNode(2);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(8);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(4);

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

const ancestor = lowestCommonAncestor(root, p, q);
console.log(ancestor ? ancestor.val : null);
A3
B4
C5
Dnull
Attempts:
2 left
💡 Hint
If one node is ancestor of the other, the ancestor node is the LCA.
🧠 Conceptual
expert
2:00remaining
Understanding LCA in a binary tree with no parent pointers
In a binary tree where nodes do not have parent pointers, which of the following statements about the Lowest Common Ancestor (LCA) algorithm is TRUE?
AThe LCA algorithm must use recursion or a stack to explore subtrees from the root downwards.
BThe LCA can be found by sorting the node values and picking the middle value.
CThe LCA is always the root node of the tree regardless of input nodes.
DThe LCA can be found by traversing from each node up to the root and comparing paths.
Attempts:
2 left
💡 Hint
Without parent pointers, you cannot move upwards from a node easily.

Practice

(1/5)
1. What is the Lowest Common Ancestor (LCA) in a binary tree?
easy
A. The root node of the binary tree
B. The lowest node that has both given nodes as descendants
C. The node with the highest value in the tree
D. The leaf node closest to the root

Solution

  1. Step 1: Understand the definition of LCA

    The Lowest Common Ancestor is the lowest node in the tree that has both given nodes as descendants (a node can be a descendant of itself).
  2. Step 2: Differentiate from other nodes

    It is not necessarily the root or the highest value node, but the shared ancestor closest to the two nodes.
  3. Final Answer:

    The lowest node that has both given nodes as descendants -> Option B
  4. Quick Check:

    LCA = lowest shared ancestor [OK]
Hint: LCA is the closest shared parent node [OK]
Common Mistakes:
  • Confusing LCA with root node
  • Thinking LCA is the node with highest value
  • Assuming LCA must be a leaf node
2. Which of the following is the correct TypeScript function signature to find the LCA in a binary tree node structure?
easy
A. function findLCA(root: TreeNode, p: TreeNode, q: TreeNode): TreeNode | null
B. function findLCA(root: TreeNode, p: number, q: number): number
C. function findLCA(root: TreeNode): TreeNode
D. function findLCA(p: TreeNode, q: TreeNode): TreeNode

Solution

  1. Step 1: Analyze parameters needed for LCA

    To find LCA, we need the root of the tree and the two nodes (p and q) to find the ancestor for.
  2. Step 2: Check return type

    The function should return the TreeNode that is the LCA or null if not found.
  3. Final Answer:

    function findLCA(root: TreeNode, p: TreeNode, q: TreeNode): TreeNode | null -> Option A
  4. Quick Check:

    Correct signature includes root, p, q nodes and returns TreeNode or null [OK]
Hint: LCA function needs root and two nodes as input [OK]
Common Mistakes:
  • Missing root parameter
  • Using wrong parameter types like numbers instead of nodes
  • Returning wrong type like number instead of TreeNode
3. Given the following TypeScript code for LCA, what will be the output if we call findLCA(root, node5, node1) where node5 and node1 are nodes with values 5 and 1 respectively?
class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
  constructor(val: number) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}

function findLCA(root: TreeNode | null, p: TreeNode, q: TreeNode): TreeNode | null {
  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;
}

// Tree structure:
//       3
//      / \
//     5   1
//    / \ / \
//   6  2 0  8
//     / \
//    7   4

const root = new TreeNode(3);
const node5 = new TreeNode(5);
const node1 = new TreeNode(1);
root.left = node5;
root.right = node1;
// ... other nodes assigned similarly

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

Solution

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

    Starting at root (3), left subtree contains node 5, right subtree contains node 1. Both left and right recursive calls return non-null nodes.
  2. Step 2: Determine LCA based on recursive returns

    Since both left and right calls return nodes, current root (3) is the LCA.
  3. Final Answer:

    3 -> Option A
  4. Quick Check:

    LCA of 5 and 1 is 3 [OK]
Hint: If nodes are in different subtrees, LCA is root [OK]
Common Mistakes:
  • Returning one of the nodes instead of their ancestor
  • Confusing node values with node references
  • Ignoring null checks in recursion
4. Identify the bug in the following TypeScript LCA function and select the correct fix:
function findLCA(root: TreeNode | null, p: TreeNode, q: TreeNode): TreeNode | null {
  if (!root) return null;
  if (root.val === p.val || root.val === q.val) return root;
  const left = findLCA(root.left, p, q);
  const right = findLCA(root.right, p, q);
  if (left && right) return root;
  return left || right;
}
medium
A. Add a base case to return root when root is null
B. Replace logical OR with AND in return statement
C. Change comparisons to check node references, not values
D. Remove recursive calls to left and right subtrees

Solution

  1. Step 1: Analyze node comparison logic

    The function compares node values (root.val === p.val), but nodes should be compared by reference to handle duplicates correctly.
  2. Step 2: Correct the comparison to use reference equality

    Change to (root === p || root === q) to compare actual nodes, not just values.
  3. Final Answer:

    Change comparisons to check node references, not values -> Option C
  4. Quick Check:

    Node reference comparison fixes LCA correctness [OK]
Hint: Compare nodes by reference, not by value [OK]
Common Mistakes:
  • Comparing node values instead of references
  • Misusing logical operators in return
  • Removing necessary recursion
5. You have a binary tree where nodes can have duplicate values. Which approach ensures correct Lowest Common Ancestor (LCA) identification for two given nodes p and q?
hard
A. Compare nodes by their values during recursion
B. Ignore duplicates and return the root as LCA
C. Return the node with the smaller value as LCA
D. Use node references (memory addresses) for comparison

Solution

  1. Step 1: Understand the problem with duplicate values

    When values repeat, comparing nodes by value can lead to wrong LCA because multiple nodes share the same value.
  2. Step 2: Use node references to uniquely identify nodes

    Comparing nodes by their references (actual objects) ensures the correct nodes are identified regardless of value duplicates.
  3. Final Answer:

    Use node references (memory addresses) for comparison -> Option D
  4. Quick Check:

    Reference comparison handles duplicates correctly [OK]
Hint: Use node references to handle duplicates safely [OK]
Common Mistakes:
  • Comparing only node values
  • Assuming smaller value node is LCA
  • Ignoring duplicates in tree
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