Lowest Common Ancestor of a Binary Tree LeetCode Solution

Last updated on January 5th, 2025 at 12:38 am

Here, we see the Lowest Common Ancestor of a Binary Tree LeetCode Solution. This Leetcode problem is solved using different approaches in many programming languages, such as C++, Java, JavaScript, Python, etc.

List of all LeetCode Solution

Topics

Tree

Companies

Amazon, Apple, Facebook, LinkedIn, Microsoft

Level of Question

Medium

Lowest Common Ancestor of a Binary Tree LeetCode Solution

Lowest Common Ancestor of a Binary Tree LeetCode Solution

1. Problem Statement

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:

binarytree

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:

binarytree

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

2. Coding Pattern Used in Solution

The coding pattern used in this code is Tree Depth First Search (DFS). The algorithm traverses the binary tree recursively, exploring each branch of the tree until it finds the nodes p and q or reaches a leaf node. This is a classic DFS approach applied to trees.

3. Code Implementation in Different Languages

3.1 Lowest Common Ancestor of a Binary Tree C++

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root || root == p || root == q) return root;
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        return !left ? right : !right ? left : root;        
    }
};

3.2 Lowest Common Ancestor of a Binary Tree Java

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        return left == null ? right : right == null ? left : root;        
    }
}

3.3 Lowest Common Ancestor of a Binary Tree JavaScript

var lowestCommonAncestor = function(root, p, q) {
  if (!root || root === p || root === q) return root;
  var resL = lowestCommonAncestor(root.left, p, q);
  var resR = lowestCommonAncestor(root.right, p, q);
  return (resL && resR) ? root : (resL || resR);    
};

3.4 Lowest Common Ancestor of a Binary Tree Python

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        if root in (None, p, q): return root
        subs = [self.lowestCommonAncestor(kid, p, q)
                for kid in (root.left, root.right)]
        return root if all(subs) else max(subs)

4. Time and Space Complexity

Time ComplexitySpace Complexity(Balanced Tree)Space Complexity(Unbalanced Tree)
C++O(N)O(log(N))O(N)
JavaO(N)O(log(N))O(N)
JavaScriptO(N)O(log(N))O(N)
PythonO(N)O(log(N))O(N)
    • The code is functionally identical across all four languages, with only syntactic differences.
    • The recursive approach is elegant and concise but can lead to stack overflow for very deep trees. An iterative approach could be used to mitigate this in practice.
    • The algorithm assumes that both p and q exist in the tree. If this assumption is not guaranteed, additional checks may be needed.

    Scroll to Top