-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfindcommonancestoroftreenodes.js
111 lines (81 loc) · 1.83 KB
/
findcommonancestoroftreenodes.js
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*Design an alogorthim and write code to find the common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: this not necessarily a binary search tree*/
"use strict";
module.exports = {
parentSolution: findCommonAncestorWithParentProperty,
noParentSolution: findCommonAncestor
};
/*This solution assumes each node has link to parent */
function findCommonAncestorWithParentProperty(n1, n2) {
if(n1 == n2) {
return n1;
}
if(!n1 || !n2) {
return null;
}
var h1 = getHeight(n1),
h2 = getHeight(n2);
if(h1 > h2) {
n1 = getAncestor(n1, h1 - h2);
} else if(h2 > h1) {
n2 = getAncestor(n2, h2 - h1);
}
while(n1 && n2) {
if(n1 == n2) {
return n1;
}
n1 = n1.parent;
n2 = n2.parent;
}
return null;
}
function getHeight(node) {
if(!node) {
return;
}
var height = 0;
while(node) {
height++;
node = node.parent;
}
return height;
}
function getAncestor(node, level) {
while(level) {
level--;
node = node.parent;
}
return node;
}
function findCommonAncestor(root, n1, n2) {
if(n1 == n2) {
return n1;
}
if(!root || !n1 || !n2) {
return null;
}
var result = findCommonAncestorHelper(root, n1, n2);
if(result.isAncestor) {
return result.node;
}
return null;
}
function findCommonAncestorHelper(root, n1, n2) {
if(!root) {
return { node: null, isAncestor: false };
}
var rLeft = findCommonAncestorHelper(root.left, n1, n2),
rRight = findCommonAncestorHelper(root.right, n1, n2);
if(rLeft.isAncestor) {
return rLeft;
}
if(rRight.isAncestor) {
return rRight;
}
if(rLeft.node && rRight.node) {
return { node: root, isAncestor: true };
}
if(root == n1 || root == n2) {
return { node: root, isAncestor: rLeft.node || rRight.node ? true : false };
}
return { node: rLeft.node ? rLeft.node : rRight.node, isAncestor: false };
}