-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlowestCommonAncestor.js
More file actions
executable file
·68 lines (51 loc) · 2.03 KB
/
lowestCommonAncestor.js
File metadata and controls
executable file
·68 lines (51 loc) · 2.03 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
// Lowest Common Ancestor (Binary Tree)
// what is lowest common ancestor?
// The lowest common ancestor (LCA) of two nodes in a binary tree is defined as the deepest node that is an ancestor of both nodes. In other words, it is the lowest node in the tree that has both nodes as descendants (where we allow a node to be a descendant of itself).
// Mental model:
// “The lowest common ancestor is like the closest shared manager in an organizational chart for two employees.”
class TreeNode {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
function lowestCommonAncestor(root, p, q) {
if (!root) return null;
// If the current node is one of the targets, return it
if (root === p || root === q) return root;
// Search in left and right subtrees
let left = lowestCommonAncestor(root.left, p, q);
let right = lowestCommonAncestor(root.right, p, q);
// If both left and right are non-null, current node is LCA
if (left && right) return root;
// Otherwise return the non-null child
return left ? left : right;
}
// Example usage:
// Creating a sample tree:
// 3
// / \
// 5 1
// / \ / \
// 6 2 0 8
// / \
// 7 4
let root = new TreeNode(3);
root.left = new TreeNode(5);
root.right = new TreeNode(1);
root.left.left = new TreeNode(6);
root.left.right = new TreeNode(2);
root.right.left = new TreeNode(0);
root.right.right = new TreeNode(8);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(4);
let p = root.left; // Node with value 5
let q = root.left.right.right; // Node with value 4
let lca = lowestCommonAncestor(root, p, q);
console.log(lca.value); // Output: 5
// time complexity: O(n) where n is the number of nodes in the tree
// space complexity: O(h) where h is the height of the tree (due to recursion stack)
// edge cases
console.log(lowestCommonAncestor(null, p, q)); // Output: null
console.log(lowestCommonAncestor(root, root, root.right)); // Output: 3