-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLowestCommonAncestorinBinaryTree_Day67.py
More file actions
77 lines (62 loc) · 1.89 KB
/
Copy pathLowestCommonAncestorinBinaryTree_Day67.py
File metadata and controls
77 lines (62 loc) · 1.89 KB
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
#Brute Approach
# Brute Force: Root-to-Node Path Method
class Solution:
def lowestCommonAncestor(self, root, p, q):
# Helper to get path from root to a node
def getPath(root, target, path):
if not root:
return False
path.append(root)
if root == target:
return True
if getPath(root.left, target, path) or getPath(root.right, target, path):
return True
path.pop()
return False
path1, path2 = [], []
getPath(root, p, path1)
getPath(root, q, path2)
# Compare paths
lca = None
for u, v in zip(path1, path2):
if u == v:
lca = u
else:
break
return lca
#Better Approach
# Better: Parent Mapping + Ancestor Set
class Solution:
def lowestCommonAncestor(self, root, p, q):
parent = {root: None}
# DFS to store parent of each node
def dfs(node):
if node.left:
parent[node.left] = node
dfs(node.left)
if node.right:
parent[node.right] = node
dfs(node.right)
dfs(root)
# Store ancestors of p
ancestors = set()
while p:
ancestors.add(p)
p = parent[p]
# First common ancestor for q
while q not in ancestors:
q = parent[q]
return q
#Optimal Approach
# Optimal: Single DFS recursion
class Solution:
def lowestCommonAncestor(self, root, p, q):
if not root or root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
return left if left else right
# Time Complexity = O(N)
# Space Complexity = O(H)