-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCh48FirstCommonAncestor.py
More file actions
88 lines (71 loc) · 2.39 KB
/
Ch48FirstCommonAncestor.py
File metadata and controls
88 lines (71 loc) · 2.39 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
77
78
79
80
81
82
83
84
85
86
87
88
# Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.
from Chapter3Stacks import LinkedList
from Ch42MinTree import produceTree, TreeNode
from Ch46Successor import createParents
from binarytree import setup, pprint, Node
def checkListforNode(node, linkedList):
current = linkedList.first
while current:
if node.data == current.data:
return node
current = current.next
return None
# this approach takes way too long-- o(log n)? a better solution would find the depths of both nodes, and once they are on even footing, traverse to the parent
def firstCommonAncestorBad(nodeA, nodeB):
pathA = LinkedList()
pathB = LinkedList()
while nodeA or nodeB:
if nodeA:
pathA.insert(nodeA.data)
if checkListforNode(nodeA, pathB) != None:
return nodeA
nodeA = nodeA.parent
if nodeB:
pathB.insert(nodeB.data)
if checkListforNode(nodeB, pathA) != None:
return nodeB
nodeB = nodeB.parent
return None
def depth(node):
depth = 0
while node.parent:
node = node.parent
depth += 1
return depth
def adjust(node, depth):
while depth > 0:
node = node.parent
depth -= 1
return node
def firstCommonAncestor(nodeA, nodeB):
print('nodeA: {a} nodeB: {b}'.format(a=nodeA.data, b=nodeB.data))
difference = depth(nodeA) - depth(nodeB)
if difference < 0:
nodeB = adjust(nodeB, abs(difference))
else:
nodeA = adjust(nodeA, difference)
while nodeA != nodeB:
nodeA = getattr(nodeA, 'parent', None)
nodeB = getattr(nodeB, 'parent', None)
if nodeA == None or nodeB == None:
return None
else:
return nodeA
def printTree(tree):
setup(
node_init_func=lambda v: TreeNode(v),
node_class=TreeNode,
null_value=None,
value_attr='data',
left_attr='left',
right_attr='right'
)
pprint(tree)
return
def main():
tree = produceTree(list(range(1,25)))
printTree(tree)
createParents(tree)
print(firstCommonAncestor(tree.right.right, tree.right.left.left.left).data)
if __name__ == "__main__":
main()