Skip to content

Commit 3043841

Browse files
committed
Added medium/binary_search_tree_lca
1 parent fee9a97 commit 3043841

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

medium/binary_search_tree_lca.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/**
2+
* Using the JavaScript language, have the function binarySearchTreeLca(strArr)
3+
* take the array of strings stored in strArr, which will contain 3 elements:
4+
* the first element will be a binary search tree with all unique values in a
5+
* preorder traversal array, the second and third elements will be two different
6+
* values, and your goal is to find the lowest common ancestor of these two
7+
* values. For example: if strArr is ["[10, 5, 1, 7, 40, 50]", "1", "7"] then
8+
* this tree looks like the following:
9+
*
10+
* [Image of Binary Search Tree](https://i.imgur.com/e4SY86q.png)
11+
*
12+
* For the input above, your program should return 5 because that is the value
13+
* of the node that is the LCA of the two nodes with values 1 and 7. You can
14+
* assume the two nodes you are searching for in the tree will exist somewhere
15+
* in the tree.
16+
*
17+
* https://www.coderbyte.com/results/bhanson:Binary%20Search%20Tree%20LCA:JavaScript
18+
*
19+
* @param {array} strArr
20+
* @return {number}
21+
*/
22+
function binarySearchTreeLca(strArr) {
23+
const preorderNodes = JSON.parse(strArr.shift());
24+
const searchNodes = strArr.map(Number);
25+
26+
const tree = new Tree();
27+
28+
preorderNodes.forEach(number => {
29+
tree.insert(number);
30+
});
31+
32+
const path0 = tree.path(searchNodes[0]);
33+
const path1 = tree.path(searchNodes[1]);
34+
35+
for (let i = path0.length - 1; i >= 0; i--) {
36+
if (path1.includes(path0[i])) {
37+
return path0[i];
38+
}
39+
}
40+
41+
return null;
42+
}
43+
44+
function Tree() {
45+
this.root = null;
46+
}
47+
48+
Tree.Node = function(key, left = null, right = null) {
49+
this.key = key;
50+
this.left = left;
51+
this.right = right;
52+
};
53+
54+
Tree.prototype.insert = function(key, nodePtr = null) {
55+
if (!this.root) {
56+
this.root = new Tree.Node(key);
57+
return;
58+
}
59+
60+
if (!nodePtr) {
61+
this.insert(key, this.root);
62+
return;
63+
}
64+
65+
if (key < nodePtr.key) {
66+
if (nodePtr.left === null) {
67+
nodePtr.left = new Tree.Node(key);
68+
} else {
69+
this.insert(key, nodePtr.left);
70+
}
71+
} else {
72+
if (nodePtr.right === null) {
73+
nodePtr.right = new Tree.Node(key);
74+
} else {
75+
this.insert(key, nodePtr.right);
76+
}
77+
}
78+
};
79+
80+
Tree.prototype.keyExists = function(key, nodePtr = null) {
81+
if (!this.root) {
82+
return false;
83+
}
84+
85+
if (!nodePtr) {
86+
return this.keyExists(key, this.root);
87+
}
88+
89+
if (key === nodePtr.key) {
90+
return true;
91+
}
92+
93+
if (key < nodePtr.key) {
94+
if (nodePtr.left === null) {
95+
return false;
96+
} else {
97+
return this.keyExists(key, nodePtr.left);
98+
}
99+
} else {
100+
if (nodePtr.right === null) {
101+
return false;
102+
} else {
103+
return this.keyExists(key, nodePtr.right);
104+
}
105+
}
106+
};
107+
108+
// Returns array showing path to node, or [] if node does not exist
109+
Tree.prototype.path = function(key, nodePtr = null, history = []) {
110+
if (!this.root) {
111+
return [];
112+
}
113+
114+
if (!nodePtr) {
115+
return this.path(key, this.root, history);
116+
}
117+
118+
if (key === nodePtr.key) {
119+
history.push(key);
120+
return history;
121+
}
122+
123+
if (key < nodePtr.key) {
124+
if (nodePtr.left === null) {
125+
return [];
126+
} else {
127+
history.push(nodePtr.key);
128+
return this.path(key, nodePtr.left, history);
129+
}
130+
} else {
131+
if (nodePtr.right === null) {
132+
return [];
133+
} else {
134+
history.push(nodePtr.key);
135+
return this.path(key, nodePtr.right, history);
136+
}
137+
}
138+
};
139+
140+
module.exports = binarySearchTreeLca;

medium/binary_search_tree_lca.test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const binarySearchTreeLca = require('./binary_search_tree_lca');
2+
3+
describe('binarySearchTreeLca()', () => {
4+
test('correctly finds lowest common ancestor', () => {
5+
expect(binarySearchTreeLca(['[10, 5, 1, 7, 40, 50]', '1', '7'])).toBe(
6+
5
7+
);
8+
9+
expect(
10+
binarySearchTreeLca(['[3, 2, 1, 12, 4, 5, 13]', '5', '13'])
11+
).toBe(12);
12+
});
13+
14+
test('passes Coderbyte.com tests', () => {
15+
expect(binarySearchTreeLca(['[10, 5, 1, 7, 40, 50]', '1', '7'])).toBe(
16+
5
17+
);
18+
19+
expect(binarySearchTreeLca(['[10, 5, 1, 7, 40, 50]', '1', '50'])).toBe(
20+
10
21+
);
22+
23+
expect(binarySearchTreeLca(['[10, 5, 1, 7, 40, 50]', '5', '10'])).toBe(
24+
10
25+
);
26+
27+
expect(
28+
binarySearchTreeLca(['[3, 2, 1, 12, 4, 5, 13]', '5', '13'])
29+
).toBe(12);
30+
31+
expect(binarySearchTreeLca(['[3, 2, 1, 12, 4, 5, 13]', '5', '4'])).toBe(
32+
4
33+
);
34+
35+
expect(binarySearchTreeLca(['[3, 2, 1, 12, 4, 5, 13]', '5', '2'])).toBe(
36+
3
37+
);
38+
39+
expect(binarySearchTreeLca(['[3, 1, 4]', '1', '4'])).toBe(3);
40+
41+
expect(
42+
binarySearchTreeLca(['[5, 3, 1, 7, 6, 12, 45, 32]', '6', '45'])
43+
).toBe(7);
44+
45+
expect(
46+
binarySearchTreeLca(['[5, 3, 1, 7, 6, 12, 45, 32]', '5', '32'])
47+
).toBe(5);
48+
49+
expect(
50+
binarySearchTreeLca(['[5, 8, 10, 12, 78, 102]', '102', '12'])
51+
).toBe(12);
52+
});
53+
});

0 commit comments

Comments
 (0)