# Lowest Common Ancestor of a Binary Tree — LC Medium

236. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes `p` and `q` as the lowest node in `T` that has both `p` and `q` as descendants (where we allow a node to be a descendant of itself).”

Example 1:

`Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1Output: 3Explanation: The LCA of nodes 5 and 1 is 3.`

Example 2:

`Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4Output: 5Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.`

Example 3:

`Input: root = [1,2], p = 1, q = 2Output: 1`

Constraints:

• The number of nodes in the tree is in the range `[2, 105]`.
• `-109 <= Node.val <= 109`
• All `Node.val` are unique.
• `p != q`
• `p` and `q` will exist in the tree.

My first approach: DFS traversal, with some stopping conditions

as you traverse through the DFS method, when the node is either equal to p or q, stop searching and jump to searching the right section. if you find another p or q, then return the original node. if you don’t find anything, then return either left or right (first node that you found first) since failure to find another node in other branch means the node is inside of the subtree that we stopped finding.

An illustration is as follows:

that is the base case example, but it is possible that the node itself becomes lowest common ancestor of the other node. illustration for that case is as follows:

code is as follows:

`# Definition for a binary tree node.# class TreeNode:#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution:    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':        # Implementation of DFS                # covering base case        if not root:            return None                return self.helperDFS(root, p, q)        def helperDFS(self, node, p, q):        if not node:            return False                if node == p or node == q:            return node                left = self.helperDFS(node.left, p, q)        right = self.helperDFS(node.right, p, q)                if left and right:            return node                return left or right`

Time complexity: O(N) as the worst case

Space complexity: O(1)

Lets compile our recursive solution that we just built

# input goes into Solution.lowestCommonAncestor(root, p, q)

# check if the root is None. it is Not. so pass first if loop

# returns the output of the recursive function that we wrote (helperDFS)

# helperDFS initiates with input root, p, q

# checks if the current input node is None. no. currently it is node 3

# checks if 3 is equal to 5 or 1, no.

# recursive call to check on the left subtree of 3

## one level down, 5 is equal to p, so return 5

# recursive call to check on the right subtree of 3

## one level down, 1 is equal to q, so return 1

# left and right values are both not None, so return the original node 3

# function ends with return output of 3

--

--

## More from Paul Kang

Data Scientist, SWE + MLE