Bird
Raised Fist0
DSA Goprogramming~20 mins

Lowest Common Ancestor in Binary Tree in DSA Go - 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 program when finding the Lowest Common Ancestor (LCA) of nodes 5 and 1 in the given binary tree?
DSA Go
package main

import "fmt"

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    if root == nil || root == p || root == q {
        return root
    }
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    if left != nil && right != nil {
        return root
    }
    if left != nil {
        return left
    }
    return right
}

func main() {
    root := &TreeNode{Val: 3}
    root.Left = &TreeNode{Val: 5}
    root.Right = &TreeNode{Val: 1}
    root.Left.Left = &TreeNode{Val: 6}
    root.Left.Right = &TreeNode{Val: 2}
    root.Right.Left = &TreeNode{Val: 0}
    root.Right.Right = &TreeNode{Val: 8}

    p := root.Left      // Node with Val 5
    q := root.Right     // Node with Val 1

    lca := lowestCommonAncestor(root, p, q)
    fmt.Println(lca.Val)
}
A3
B5
C1
D6
Attempts:
2 left
💡 Hint
Think about the lowest node that has both nodes 5 and 1 as descendants.
❓ Predict Output
intermediate
2:00remaining
Output of LCA for nodes in the same subtree
What is the output of the program when finding the Lowest Common Ancestor (LCA) of nodes 6 and 2 in the given binary tree?
DSA Go
package main

import "fmt"

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    if root == nil || root == p || root == q {
        return root
    }
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    if left != nil && right != nil {
        return root
    }
    if left != nil {
        return left
    }
    return right
}

func main() {
    root := &TreeNode{Val: 3}
    root.Left = &TreeNode{Val: 5}
    root.Right = &TreeNode{Val: 1}
    root.Left.Left = &TreeNode{Val: 6}
    root.Left.Right = &TreeNode{Val: 2}
    root.Right.Left = &TreeNode{Val: 0}
    root.Right.Right = &TreeNode{Val: 8}

    p := root.Left.Left   // Node with Val 6
    q := root.Left.Right  // Node with Val 2

    lca := lowestCommonAncestor(root, p, q)
    fmt.Println(lca.Val)
}
A2
B6
C5
D3
Attempts:
2 left
💡 Hint
Both nodes are in the left subtree of the root.
🔧 Debug
advanced
2:00remaining
Identify the error in LCA function implementation
What error will occur when running this LCA function code?
DSA Go
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    if root == p || root == q {
        return root
    }
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    if left != nil && right != nil {
        return root
    }
    if left != nil {
        return left
    }
    return right
}
APanic due to nil pointer dereference if p or q is nil
BNo error, works correctly
CInfinite recursion causing stack overflow
DCompilation error due to missing return statement
Attempts:
2 left
💡 Hint
Check how the function handles nil and base cases.
❓ Predict Output
advanced
2:00remaining
Output when one node is ancestor of the other
What is the output of the program when finding the Lowest Common Ancestor (LCA) of nodes 5 and 6 in the given binary tree?
DSA Go
package main

import "fmt"

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    if root == nil || root == p || root == q {
        return root
    }
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    if left != nil && right != nil {
        return root
    }
    if left != nil {
        return left
    }
    return right
}

func main() {
    root := &TreeNode{Val: 3}
    root.Left = &TreeNode{Val: 5}
    root.Right = &TreeNode{Val: 1}
    root.Left.Left = &TreeNode{Val: 6}
    root.Left.Right = &TreeNode{Val: 2}
    root.Right.Left = &TreeNode{Val: 0}
    root.Right.Right = &TreeNode{Val: 8}

    p := root.Left      // Node with Val 5
    q := root.Left.Left // Node with Val 6

    lca := lowestCommonAncestor(root, p, q)
    fmt.Println(lca.Val)
}
A6
B3
C2
D5
Attempts:
2 left
💡 Hint
If one node is ancestor of the other, the ancestor is the LCA.
🧠 Conceptual
expert
2:00remaining
Understanding LCA algorithm behavior with missing nodes
If one of the nodes (p or q) is not present in the binary tree, what will the LCA function return?
AReturns the node that is present if found, otherwise nil
BReturns nil because both nodes must be present to find LCA
CReturns the root node always regardless of presence
DCauses a runtime error due to nil pointer dereference
Attempts:
2 left
💡 Hint
Consider how the function returns when it finds p or q and when it doesn't.

Practice

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

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: Identify the deepest common ancestor

    Among all common ancestors, the LCA is the one farthest from the root (deepest).
  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 lowest node common to both paths [OK]
Common Mistakes:
  • Confusing LCA with root node always
  • Thinking LCA is the node with smaller value
  • Assuming LCA is a child of both nodes
2. Which of the following is the correct Go function signature to find the LCA of two nodes in a binary tree?
easy
A. func lowestCommonAncestor(root TreeNode, p *TreeNode, q TreeNode) *TreeNode
B. func lowestCommonAncestor(root TreeNode, p TreeNode, q TreeNode) TreeNode
C. func lowestCommonAncestor(root *TreeNode, p TreeNode, q *TreeNode) TreeNode
D. func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode

Solution

  1. Step 1: Understand pointer usage in Go for tree nodes

    Tree nodes are usually passed as pointers to avoid copying and to allow modification.
  2. Step 2: Check parameter and return types

    The function should accept pointers to TreeNode for root, p, and q, and return a pointer to TreeNode.
  3. Final Answer:

    func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode -> Option D
  4. Quick Check:

    Use pointers for nodes in Go function signature [OK]
Hint: Use pointers for tree nodes in Go functions [OK]
Common Mistakes:
  • Passing nodes by value instead of pointer
  • Mixing pointer and value types in parameters
  • Returning value instead of pointer
3. Given the following Go code snippet, what will be the output when finding the LCA of nodes 5 and 1?
type TreeNode struct {
    Val int
    Left, Right *TreeNode
}

func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    if root == nil || root == p || root == q {
        return root
    }
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    if left != nil && right != nil {
        return root
    }
    if left != nil {
        return left
    }
    return right
}

func main() {
    root := &TreeNode{Val: 3}
    root.Left = &TreeNode{Val: 5}
    root.Right = &TreeNode{Val: 1}
    root.Left.Left = &TreeNode{Val: 6}
    root.Left.Right = &TreeNode{Val: 2}
    root.Right.Left = &TreeNode{Val: 0}
    root.Right.Right = &TreeNode{Val: 8}

    lca := lowestCommonAncestor(root, root.Left, root.Right)
    fmt.Println(lca.Val)
}
medium
A. 3
B. 5
C. 1
D. 2

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.
  2. Step 2: Both left and right recursive calls return non-nil nodes

    Since left and right are both non-nil, root (3) is the LCA.
  3. Final Answer:

    3 -> Option A
  4. Quick Check:

    LCA(5,1) = 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
  • Not handling nil checks properly
4. The following Go function is intended to find the LCA of two nodes in a binary tree. What is the bug?
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    if root == nil {
        return nil
    }
    if root.Val == p.Val || root.Val == q.Val {
        return root
    }
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    if left != nil {
        return left
    }
    if right != nil {
        return right
    }
    return root
}
medium
A. Returns root when both left and right are nil instead of nil
B. Does not check for nil root at start
C. Compares node pointers instead of values
D. Does not recurse on left subtree

Solution

  1. Step 1: Analyze return conditions after recursion

    If both left and right are nil, the function incorrectly returns root instead of nil.
  2. Step 2: Understand correct base case for no ancestor found

    When neither subtree contains p or q, function should return nil, not root.
  3. Final Answer:

    Returns root when both left and right are nil instead of nil -> Option A
  4. Quick Check:

    Return nil if no ancestor found [OK]
Hint: Return nil if both sides are nil, not root [OK]
Common Mistakes:
  • Returning root instead of nil when no match
  • Missing nil check at start
  • Comparing values instead of pointers incorrectly
5. You have a binary tree where nodes can have duplicate values. How should you modify the LCA function to correctly find the LCA of two given nodes p and q?
hard
A. Compare node values only since duplicates don't affect LCA
B. Compare node pointers instead of node values to identify nodes
C. Use node values and parent pointers to find LCA
D. Return the node with smaller value as LCA

Solution

  1. Step 1: Understand problem with duplicate values

    When values are duplicated, comparing values alone can confuse nodes.
  2. Step 2: Use node pointers to uniquely identify nodes

    Comparing pointers ensures the exact nodes p and q are found, not just matching values.
  3. Step 3: Modify function to compare pointers (e.g., root == p)

    This guarantees correct LCA even with duplicate values.
  4. Final Answer:

    Compare node pointers instead of node values to identify nodes -> Option B
  5. Quick Check:

    Use pointers, not values, for unique node identity [OK]
Hint: Use pointers to identify nodes uniquely with duplicates [OK]
Common Mistakes:
  • Comparing only values causing wrong LCA
  • Assuming duplicates don't affect LCA
  • Using parent pointers unnecessarily
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