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).”

1
2
3
4
5
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.

ex1

1
2
3
4
5
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.

ex2

1
2
3
4
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, 105].
  • -10^9 <= Node.val <= 10^9
  • All Node.val are unique.
  • p != q
  • p and q will exist in the tree.

Solution:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        
        List<TreeNode> parentNodes1 = new ArrayList();
        List<TreeNode> parentNodes2 = new ArrayList();
        
        search(root, p, parentNodes1);
        search(root, q, parentNodes2);
        
        int n = Math.min(parentNodes1.size(), parentNodes2.size());
        TreeNode lca = root;
        for (int i = 1; i < n; i++) {
            if (parentNodes1.get(i).val == parentNodes2.get(i).val) {
                lca = parentNodes1.get(i);
            } else {
                break;
            }
        }
        return lca;

    }
    
    boolean search(TreeNode current, TreeNode target, List<TreeNode> path) {
        if (current == null) return false;
        
        path.add(current);
             
        if (current.val == target.val) {
            return true;
        }
        
        if (search(current.left, target, path)) {
            return true;
        }
        
        if (search(current.right, target, path)) {
            return true;
        }
        
        path.remove(path.size() - 1);
        
        return false;
    }
}

## Solution 2

```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
     
       List<TreeNode> path1 = new ArrayList<>(); 
       search(root, p.val, path1);
        
       List<TreeNode> path2 = new ArrayList<>();
       search(root, q.val, path2);

       for (int i = Math.min(path1.size(), path2.size()) - 1; i >= 0; i--) {
            var p1 = path1.get(i);
            var p2 = path2.get(i);
            if (p1.val == p2.val) return p1;
        }
        return null;
    }
    
    TreeNode search(TreeNode node, int val, List<TreeNode> paths) {
        if (node == null) return null;
        
        paths.add(node);
        
        if (node.val == val) {
            return node;
        }
        
        TreeNode s = search(node.left, val, paths);
        if (s != null) return s;
        s = search(node.right, val, paths);
        if (s != null) return s;
        paths.remove(node);
        return null;
    }

}

Solution 2021-11-18

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        Stack<TreeNode> stack = new Stack<>();
         Map<TreeNode, TreeNode> nodeParent = new HashMap<>();
        
        stack.push(root);
        nodeParent.put(root, null);
        
        while (!nodeParent.containsKey(p) || !nodeParent.containsKey(q)) {
            TreeNode node = stack.pop();
            
            if (node.right != null) {
                nodeParent.put(node.right, node);
                stack.push(node.right);
            }
            
            if (node.left != null) {
                nodeParent.put(node.left, node);
                stack.push(node.left);
            }
        }
        
        Set<TreeNode> parents = new LinkedHashSet<>();
        while (p != null) {
            parents.add(p);
            p = nodeParent.get(p);
        }

        while (q != null && !parents.contains(q)) {
            q = nodeParent.get(q);
        }
        
        return q;
    }
}

Solution 2022-01-29

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        
        Map<TreeNode, TreeNode> nodeParent = new HashMap<>();
        nodeParent.put(root, null);
        
        while (!nodeParent.containsKey(p) || !nodeParent.containsKey(q)) {
            TreeNode node = stack.pop();
            
            if (node.right != null) {
                nodeParent.put(node.right, node);
                stack.push(node.right);
            }
            
            if (node.left != null) {
                nodeParent.put(node.left, node);
                stack.push(node.left);
            }
        }
        
        
        Set<TreeNode> parents = new LinkedHashSet<>();
        // 5
        while (p != null) {
            parents.add(p);
            p = nodeParent.get(p);
        }
        
        while (q != null && !parents.contains(q)) {
            q = nodeParent.get(q);
        }
        
        return q;
    }
}