Skip to content

Commit 43b932f

Browse files
committed
Add problem 235 - Lowest Common Ancestor Of A Binary Search Tree
1 parent a278a8e commit 43b932f

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from problems.util.tree_node import TreeNode
2+
3+
4+
class LowestCommonAncestorOfABinarySearchTree:
5+
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> TreeNode | None:
6+
# Special case
7+
if root is None or p is None or q is None:
8+
return None
9+
if root.val > p.val and root.val > q.val:
10+
# If value of root is greater than values at both p and q,
11+
# it means LCA can only be in the left subtree
12+
return self.lowestCommonAncestor(root.left, p, q)
13+
elif root.val < p.val and root.val < q.val:
14+
# If value of root is smaller than values at both p and q,
15+
# it means LCA can only be in the right subtree
16+
return self.lowestCommonAncestor(root.right, p, q)
17+
else:
18+
# We will reach here if value is root is in between values at
19+
# p and q. If this happens, then only root can be the LCA
20+
return root
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import unittest
2+
3+
from problems.tree.lowest_common_ancestor_of_a_binary_search_tree import LowestCommonAncestorOfABinarySearchTree
4+
from problems.util.tree_node import TreeNode
5+
6+
7+
class LowestCommonAncestorOfABinarySearchTreeTest(unittest.TestCase):
8+
# noinspection PyTypeChecker
9+
def test_lowest_common_ancestor(self):
10+
lowest_common_ancestor_of_a_binary_search_tree = LowestCommonAncestorOfABinarySearchTree()
11+
12+
# Test case 1: Both nodes are null
13+
self.assertIsNone(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(None, None, None))
14+
15+
# Test case 2: One node is null
16+
root = TreeNode(3)
17+
p = TreeNode(1)
18+
self.assertIsNone(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(root, None, p))
19+
self.assertIsNone(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(root, p, None))
20+
21+
# Test case 3: Both nodes are the same
22+
self.assertEqual(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(p, p, p), p)
23+
24+
# Test case 4: LCA is root
25+
q = TreeNode(5)
26+
root.left = p
27+
root.right = q
28+
self.assertEqual(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(root, p, q), root)
29+
30+
# Test case 5: LCA is in the left subtree
31+
p2 = TreeNode(0)
32+
p.left = p2
33+
self.assertEqual(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(root, p2, p), p)
34+
35+
# Test case 6: LCA is in the right subtree
36+
q2 = TreeNode(6)
37+
q.right = q2
38+
self.assertEqual(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(root, q, q2), q)
39+
40+
# Test case 7: Complex tree
41+
root2 = TreeNode(6)
42+
p3 = TreeNode(2)
43+
q3 = TreeNode(8)
44+
root2.left = TreeNode(0)
45+
root2.right = TreeNode(4)
46+
root2.left.left = TreeNode(3)
47+
root2.left.right = TreeNode(5)
48+
self.assertEqual(lowest_common_ancestor_of_a_binary_search_tree.lowestCommonAncestor(root2, p3, q3), root2)
49+
50+
51+
if __name__ == '__main__':
52+
unittest.main()

0 commit comments

Comments
 (0)