1 minute read

Problem Statement

problem

Intuition

The problem asks to find the Lowest Common Ancestor (LCA) of two nodes in a binary tree where each node has a parent pointer. The idea is to trace the paths of the two nodes to the root and find where they diverge. The last common node in their paths is the LCA.

Approach

  1. We first check if one node is a descendant of the other using Depth First Search (DFS).
  2. If neither is a descendant of the other, we trace both nodes’ paths to the root using the parent pointers and compare the paths.
  3. The last common node between the two paths is the LCA.

Complexity

  • Time complexity: \(O(h)\), where \(h\) is the height of the tree. This is because we traverse from each node to the root, and the height of the tree determines the maximum number of steps.

  • Space complexity: \(O(h)\), as we store the path from each node to the root, which can be at most the height of the tree.

Code

"""
# Definition for a Node.
class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.parent = None
"""

class Solution:
    def dfs(self, root, target):
        if not root:
            return False
        if root is target:
            return True
        return self.dfs(root.left, target) or self.dfs(root.right, target)

    def helper(self, p, q):
        parents1 = []
        parents2 = []
        while p.parent or q.parent:
            if p.parent:
                p = p.parent
                parents1.append(p)
            if q.parent:
                q = q.parent
                parents2.append(q)

        parents1.reverse()
        parents2.reverse()
        prev = None
        for i in range(min(len(parents1), len(parents2))):
            if parents1[i] is not parents2[i]:
                return prev
            prev = parents1[i] if parents1[i] else parents2[i]
        return prev


    def lowestCommonAncestor(self, p: 'Node', q: 'Node') -> 'Node':
        if self.dfs(p, q):
            return p
        if self.dfs(q, p):
            return q
        return self.helper(p, q)