diff --git a/src/main/java/com/leetcode/medium/LowestCommonAncestorOfABinaryTree236.java b/src/main/java/com/leetcode/medium/LowestCommonAncestorOfABinaryTree236.java new file mode 100644 index 0000000..15538de --- /dev/null +++ b/src/main/java/com/leetcode/medium/LowestCommonAncestorOfABinaryTree236.java @@ -0,0 +1,30 @@ +// Tags: Tree, DFS +package com.leetcode.medium; + +import com.leetcode.datastructure.TreeNode; + +public class LowestCommonAncestorOfABinaryTree236 { + /* + Time complexity: O(N), + where N is the number of nodes in the binary tree. + In the worst case we might be visiting all the nodes of the binary tree. + + Space complexity: O(N). + This is because the maximum amount of space utilized by the recursion stack would be N + since the height of a skewed binary tree could be N. + */ + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == p || root == q || root == null) { + return root; + } + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + if (left != null && right != null) { + return root; + } + if (left != null) { + return left; + } + return right; + } +} diff --git a/src/test/java/com/leetcode/medium/LowestCommonAncestorOfABinaryTree236Test.java b/src/test/java/com/leetcode/medium/LowestCommonAncestorOfABinaryTree236Test.java new file mode 100644 index 0000000..a21eadc --- /dev/null +++ b/src/test/java/com/leetcode/medium/LowestCommonAncestorOfABinaryTree236Test.java @@ -0,0 +1,47 @@ +package com.leetcode.medium; + +import com.leetcode.datastructure.TreeNode; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class LowestCommonAncestorOfABinaryTree236Test { + private LowestCommonAncestorOfABinaryTree236 solution; + + @BeforeEach + void setUp() { + solution = new LowestCommonAncestorOfABinaryTree236(); + } + + @Test + void testLowestCommonAncestor_Example1() { + TreeNode root = new TreeNode(3, + new TreeNode(5, new TreeNode(6), new TreeNode(2, new TreeNode(7), new TreeNode(4))), + new TreeNode(1, new TreeNode(0), new TreeNode(8))); + TreeNode p = root.left; // Node with value 5 + TreeNode q = root.right; // Node with value 1 + TreeNode result = solution.lowestCommonAncestor(root, p, q); + assertEquals(root, result); + } + + @Test + void testLowestCommonAncestor_Example2() { + TreeNode root = new TreeNode(3, + new TreeNode(5, new TreeNode(6), new TreeNode(2, new TreeNode(7), new TreeNode(4))), + new TreeNode(1, new TreeNode(0), new TreeNode(8))); + TreeNode p = root.left; // Node with value 5 + TreeNode q = root.left.right.right; // Node with value 4 + TreeNode result = solution.lowestCommonAncestor(root, p, q); + assertEquals(p, result); + } + + @Test + void testLowestCommonAncestor_Example3() { + TreeNode root = new TreeNode(1, new TreeNode(2), null); + TreeNode p = root; // Node with value 1 + TreeNode q = root.left; // Node with value 2 + TreeNode result = solution.lowestCommonAncestor(root, p, q); + assertEquals(p, result); + } +}