Skip to content
Hello Python

Checking your account…

Sign in to save your code and progress across devices. The lesson and problem statement remain public.

Loading the interactive Interview workspace.If it does not appear, the problem and learning material remain readable, but browser execution is unavailable.Reload Interview workspace

Problem

Implement Solution.lowestCommonAncestor(root, pValue, qValue). Values identify two existing BST nodes. Return the value of their lowest common ancestor; this value-based contract makes the node result serializable.

Starter code

class Solution:
    def lowestCommonAncestor(self, root, pValue, qValue):
        pass
Test cases

root-split

{
  "args": [
    {
      "$type": "binary-tree",
      "values": [
        6,
        2,
        8,
        0,
        4,
        7,
        9,
        null,
        null,
        3,
        5
      ]
    },
    2,
    8
  ]
}

Expected: 6

Wizard outline
  1. Step 1: Initialize Solution.lowestCommonAncestor

    Replace the empty starter with the first real state owned by Solution.lowestCommonAncestor. A small, named state is easier to verify than a complete algorithm. Establish it before adding the branch or loop that changes it.

  2. Step 2: Pass the Root Split case

    Complete the readable core algorithm for one representative Interview case. Move left when both targets are smaller, right when both are larger, otherwise stop at their split.

  3. Step 3: Harden the Target Is Ancestor boundary

    Repair the reviewed boundary and pass the complete submission contract. When both targets lie on one ordered side, their LCA must also lie there. The first node where they split or equal the current node is an ancestor of both and no descendant can remain ancestor of both, making it lowest.

Footguns and prerequisites
  • A target can itself be the ancestor and must be returned at equality.
  • trees and graphs
Reviewed references
Practice prerequisites
  • Carry State Through Tree DFS(opens in a new tab)

    Carry State Through Tree DFS isolates the running total passed to a node equals the sum from the root through that node, independent of sibling branches. That focused state discipline is required when implementing lowest common ancestor bst as a complete Interview Problem.

Recommended approach and implementation

Normalize lower/higher target values and walk from root: go left above both, right below both, otherwise return the current split value.

Why it works: When both targets lie on one ordered side, their LCA must also lie there. The first node where they split or equal the current node is an ancestor of both and no descendant can remain ancestor of both, making it lowest.

class Solution:
    def lowestCommonAncestor(self, root, pValue, qValue):
        """
        Checkpoint 1: initialize the state owned by this Interview contract.
        Checkpoint 2: assemble the primary transition without hiding the boundary.
        """
        lower, higher = sorted((pValue, qValue))
        current = root
        while current:
            if current.val < lower:
                current = current.right
            elif current.val > higher:
                current = current.left
            else:
                return current.val