PracHub
QuestionsPremiumLearningGuidesInterview PrepCoaches

Quick Overview

This question evaluates understanding of tree algorithms and recursive DFS traversal for computing the lowest common ancestor in an N-ary tree, including handling node references, subtree detection, and correctness in a single traversal.

  • medium
  • Scale AI
  • Coding & Algorithms
  • Software Engineer

Find LCA in a N-ary tree via DFS

Company: Scale AI

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

You are given the root of a **rooted N-ary tree** (each node can have zero or more children) and two distinct nodes `p` and `q` that belong to the tree. Design an algorithm to find the **lowest common ancestor (LCA)** of `p` and `q`. The LCA of two nodes `p` and `q` in a rooted tree is defined as the lowest (i.e., deepest) node in the tree that has both `p` and `q` as descendants (where we allow a node to be a descendant of itself). ### Input - A reference to the root node of an N-ary tree. Each node has: - A value. - A list of child nodes. - Two references `p` and `q` to distinct nodes in the same tree. ### Output - A reference to the node that is the LCA of `p` and `q`. ### Constraints - The tree can have up to \(10^5\) nodes. - The tree is not necessarily balanced. - Node values may not be unique; you must work with node references, not just values. ### Requirements 1. Describe a **recursive DFS-based algorithm** that finds the LCA in a single traversal of the tree. 2. Your DFS helper for each node should conceptually return a pair of booleans (or equivalent) indicating whether `p` or `q` was found in that node’s subtree. - The first node where both flags are true in the returned pair should be identified as the LCA. 3. Implement this algorithm in your preferred programming language. - You may define your own N-ary tree node structure (e.g., with a `children` list). Explain the algorithm and then provide the implementation.

Quick Answer: This question evaluates understanding of tree algorithms and recursive DFS traversal for computing the lowest common ancestor in an N-ary tree, including handling node references, subtree detection, and correctness in a single traversal.

You are given a rooted N-ary tree and two distinct nodes p and q. Find their lowest common ancestor (LCA) using one recursive DFS traversal. For this coding version, the tree is serialized as (id, value, children), where id is unique, value may be duplicated, and children is a list of child nodes in the same format. The ids p_id and q_id act as stand-ins for node references. Your DFS helper should return a pair of booleans indicating whether p or q appears in the current subtree. Because the traversal is postorder, the first node whose subtree reports both booleans is the LCA.

Constraints

  • 1 <= number of nodes <= 10^5
  • The tree may be highly unbalanced
  • Node ids are unique, but node values may repeat
  • p_id and q_id are distinct and both exist in the tree

Examples

Input: ((1, 100, [(2, 200, [(5, 500, []), (6, 600, [])]), (3, 300, []), (4, 400, [(7, 700, []), (8, 800, [])])]), 5, 8)

Expected Output: 1

Explanation: Node 5 is in the subtree of 2 and node 8 is in the subtree of 4, so their lowest common ancestor is the root node 1.

Input: ((1, 100, [(2, 200, [(5, 500, []), (6, 600, [])]), (3, 300, []), (4, 400, [(7, 700, []), (8, 800, [])])]), 5, 6)

Expected Output: 2

Explanation: Nodes 5 and 6 are both direct children of node 2, so node 2 is their LCA.

Input: ((1, 100, [(2, 200, [(5, 500, []), (6, 600, [])]), (3, 300, []), (4, 400, [(7, 700, []), (8, 800, [])])]), 2, 6)

Expected Output: 2

Explanation: A node can be an ancestor of itself. Since node 2 is an ancestor of node 6, the LCA is 2.

Input: ((10, 7, [(20, 7, []), (30, 7, [(40, 7, []), (50, 7, [])])]), 40, 50)

Expected Output: 30

Explanation: All node values are duplicated, so ids must be used. Nodes 40 and 50 are both under node 30, making 30 the LCA.

Input: (None, 1, 2)

Expected Output: None

Explanation: An empty tree has no nodes, so no LCA exists.

Input: ((1, 9, [(2, 9, []), (3, 9, [])]), 2, 99)

Expected Output: None

Explanation: Node 99 does not appear in the tree, so there is no valid LCA.

Solution

def solution(tree, p_id, q_id):
    if tree is None:
        return None

    root_id = tree[0]
    res = {}
    lca_id = None

    stack = [(tree, False)]  # (node, visited)
    while stack:
        node, visited = stack.pop()
        if node is None:
            continue
        node_id, _, children = node
        if not visited:
            stack.append((node, True))
            for child in children:
                stack.append((child, False))
        else:
            found_p = (node_id == p_id)
            found_q = (node_id == q_id)
            for child in children:
                cid = child[0]
                cp, cq = res.get(cid, (False, False))
                if cp:
                    found_p = True
                if cq:
                    found_q = True
            if lca_id is None and found_p and found_q:
                lca_id = node_id
            res[node_id] = (found_p, found_q)

    rp, rq = res.get(root_id, (False, False))
    return lca_id if rp and rq else None

Time complexity: O(n). Space complexity: O(h), where h is the height of the tree due to recursion stack.

Hints

  1. Let each DFS call return two booleans: whether p was found in the current subtree and whether q was found in the current subtree.
  2. Use postorder traversal. If children are processed before the current node, the first node whose returned pair becomes (True, True) is the deepest common ancestor.
Last updated: Apr 27, 2026

Loading coding console...

PracHub

Master your tech interviews with 7,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement a Dependency-Aware Task Scheduler - Scale AI (easy)
  • Schedule Ready Tasks by Deadline - Scale AI (medium)
  • Implement a Task Processor - Scale AI (medium)
  • Update a Neuron Grid - Scale AI (medium)
  • Implement multi-head attention and LLM sampling - Scale AI (easy)