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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy