--- title: '236. Lowest Common Ancestor of a Binary Tree' description: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree icon: dot topics: - { name: "Tree", slug: "tree" } - { name: "Depth-First Search", slug: "depth-first-search" } - { name: "Binary Tree", slug: "binary-tree" } - { name: "Binary Lifting", slug: "binary-lifting" } - { name: "Lowest Common Ancestor", slug: "lowest-common-ancestor" } issue: "https://github.com/prdlk/leetcode/issues/98" sidebar: label: 'Lowest Common Ancestor of a Binary Tree' badge: 'Medium' --- ### Example 1: - Input: `root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1` - Output: `3` - Explanation: 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 = 4` - Output: `5` - Explanation: 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 = 2` - Output: `1` ### Constraints: - The number of nodes in the tree is in the range [2, 10^5]. - `-10^9 <= Node.val <= 10^9` - All Node.val are unique. - `p != q` - p and q will exist in the tree. ## Approach ```mermaid flowchart TD S(["lowestCommonAncestor(root, p, q)"]) --> B{"not root?"} B -- yes --> N(["return None"]) B -- no --> M{"root == p or root == q?"} M -- yes --> R(["return root — a node is its own ancestor"]) M -- no --> L["l = self.lowestCommonAncestor(root.left, p, q)"] L --> Q["r = self.lowestCommonAncestor(root.right, p, q)"] Q --> D{"l and r?"} D -- yes --> A(["return root — p and q were found on different sides"]) D -- no --> E(["return l or r — pass up whichever side found something"]) ``` ## Solution ```py # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def lowestCommonAncestor( self, root: "TreeNode", p: "TreeNode", q: "TreeNode" ) -> "TreeNode": if not root: return None if root == p or root == q: return root l = self.lowestCommonAncestor(root.left, p, q) r = self.lowestCommonAncestor(root.right, p, q) if l and r: return root else: return l or r ```