Skip to content

Commit c12cc21

Browse files
committed
Add lowest common ancestor LC medium Python
1 parent 0ade4d5 commit c12cc21

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description
3+
4+
Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.
5+
6+
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).”
7+
8+
Example 1:
9+
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
10+
Output: 6
11+
Explanation: The LCA of nodes 2 and 8 is 6.
12+
13+
Example 2:
14+
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
15+
Output: 2
16+
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
17+
18+
Example 3:
19+
Input: root = [2,1], p = 2, q = 1
20+
Output: 2
21+
22+
Constraints:
23+
The number of nodes in the tree is in the range [2, 105].
24+
-109 <= Node.val <= 109
25+
All Node.val are unique.
26+
p != q
27+
p and q will exist in the BST.
28+
"""
29+
30+
class TreeNode:
31+
def __init__(self, val=0, left=None, right=None):
32+
self.val = val
33+
self.left = left
34+
self.right = right
35+
36+
def lowestCommonAncestor(root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
37+
commonAncestor = None
38+
39+
def bfs(node) -> bool:
40+
nonlocal commonAncestor
41+
42+
if node is None:
43+
return False
44+
45+
left = bfs(node.left)
46+
right = bfs(node.right)
47+
isCurrentNode = node.val == p.val or node.val == q.val
48+
49+
if (left and right) or (left and isCurrentNode) or (right and isCurrentNode):
50+
commonAncestor = node
51+
52+
return left or right or isCurrentNode
53+
54+
bfs(root)
55+
56+
return commonAncestor
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from lowest_common_ancestor import lowestCommonAncestor, TreeNode
2+
import unittest
3+
4+
class TestLowestCommonAncestor(unittest.TestCase):
5+
def test_returns_lowest_common_ancestor(self):
6+
"""Takes in a tree and two nodes and returns the lowest common ancestor"""
7+
root = TreeNode(6)
8+
root.left = TreeNode(2)
9+
root.right = TreeNode(8)
10+
root.left.left = TreeNode(0)
11+
root.left.right = TreeNode(4)
12+
root.right.left = TreeNode(7)
13+
root.right.right = TreeNode(9)
14+
root.left.right.left = TreeNode(3)
15+
root.left.right.right = TreeNode(5)
16+
17+
p = root.left
18+
q = root.right
19+
20+
result = lowestCommonAncestor(root, p, q)
21+
self.assertEqual(result, root)
22+
23+
def test_returns_lowest_common_ancestor_when_one_node_is_ancestor(self):
24+
"""Takes in a tree and two nodes where one is the ancestor and returns the ancestor"""
25+
root = TreeNode(6)
26+
root.left = TreeNode(2)
27+
root.right = TreeNode(8)
28+
root.left.left = TreeNode(0)
29+
30+
p = root.left
31+
q = root.left.left
32+
33+
result = lowestCommonAncestor(root, p, q)
34+
self.assertEqual(result, root.left)
35+
36+
if __name__ == "__main__":
37+
unittest.main()

src/leetcode/medium/medium.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
- [Longest Palindrome Subsequence](longest-palindrome-subsequence)
4545
- [Longest Palindromic Substring](longest-palindrome-substring)
4646
- [Longest Repeating Character Replacement](longest-repeating-character-replacement)
47+
- [Lowest Common Ancestors](lowest-common-ancestor)
4748
- [Longest Substring Without Repeating Characters](longest-substring-without-repeating-characters)
4849
- [LRU Cache](lru-cache)
4950
- [Lowest Common Ancestor of Binary Search Tree](lowest-common-ancestor-of-bst)

0 commit comments

Comments
 (0)