Skip to content

Commit 0e3392d

Browse files
committed
LCA with access to parent node: done
1 parent c903b26 commit 0e3392d

File tree

3 files changed

+139
-11
lines changed

3 files changed

+139
-11
lines changed
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ctci.treesandgraphs;
2+
3+
/**
4+
* @author rampatra
5+
* @since 2019-02-21
6+
*/
7+
public class BuildOrder {
8+
9+
10+
11+
public static void main(String[] args) {
12+
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.ctci.treesandgraphs;
2+
3+
/**
4+
* Design an algorithm and write code to find the first common ancestor of two nodes in a binary
5+
* tree. Avoid storing additional nodes in a data structure. Also, for this question, the tree node
6+
* has access to its parent node. NOTE: This is not necessarily a binary search tree.
7+
*
8+
* @author rampatra
9+
* @since 2019-02-23
10+
*/
11+
public class LeastCommonAncestorWithParentAccess {
12+
13+
/**
14+
* This is a simple approach where we start with two references, one pointing to {@code node a} and another
15+
* pointing to {@code node b}. We move the reference pointing to the deeper node upwards, if required, so that
16+
* both the references are at the same depth from root. After both the references are at same depth, we simply
17+
* move both the references upwards until they merge. The node at which they merge is our LCA.
18+
*
19+
* @param a
20+
* @param b
21+
* @return the least common ancestor node
22+
*/
23+
private static TreeNode findLCA(TreeNode a, TreeNode b) {
24+
if (a == null || b == null) {
25+
return null;
26+
}
27+
28+
int depthA = depth(a);
29+
int depthB = depth(b);
30+
// be little careful when both nodes are at same depth
31+
TreeNode shallowNode = depthA < depthB ? a : b;
32+
TreeNode deeperNode = depthB > depthA ? b : a;
33+
34+
// move deeper node reference upwards so that both the references are at same depth
35+
deeperNode = goUpBy(deeperNode, Math.abs(depthA - depthB));
36+
37+
while (shallowNode != deeperNode && shallowNode != null && deeperNode != null) {
38+
shallowNode = shallowNode.parent;
39+
deeperNode = deeperNode.parent;
40+
}
41+
42+
return shallowNode;
43+
}
44+
45+
private static int depth(TreeNode node) {
46+
int d = 0;
47+
while (node != null && node.parent != null) {
48+
d++;
49+
node = node.parent;
50+
}
51+
return d;
52+
}
53+
54+
private static TreeNode goUpBy(TreeNode node, int levelsUp) {
55+
int c = 0;
56+
while (node != null && c < levelsUp) {
57+
node = node.parent;
58+
c++;
59+
}
60+
return node;
61+
}
62+
63+
private static class TreeNode {
64+
int val;
65+
TreeNode parent;
66+
TreeNode left;
67+
TreeNode right;
68+
69+
TreeNode(int val) {
70+
this.val = val;
71+
}
72+
}
73+
74+
public static void main(String[] args) {
75+
/*
76+
The binary tree looks like:
77+
78+
4
79+
/ \
80+
5 8
81+
/ \ / \
82+
1 3 2 9
83+
/ \
84+
0 7
85+
86+
*/
87+
TreeNode treeRoot = new TreeNode(4);
88+
treeRoot.left = new TreeNode(5);
89+
treeRoot.left.parent = treeRoot;
90+
treeRoot.right = new TreeNode(8);
91+
treeRoot.right.parent = treeRoot;
92+
treeRoot.left.left = new TreeNode(1);
93+
treeRoot.left.left.parent = treeRoot.left;
94+
treeRoot.left.right = new TreeNode(3);
95+
treeRoot.left.right.parent = treeRoot.left;
96+
treeRoot.left.left.left = new TreeNode(0);
97+
treeRoot.left.left.left.parent = treeRoot.left.left;
98+
treeRoot.right.left = new TreeNode(2);
99+
treeRoot.right.left.parent = treeRoot.right;
100+
treeRoot.right.right = new TreeNode(9);
101+
treeRoot.right.right.parent = treeRoot.right;
102+
treeRoot.right.left.right = new TreeNode(7);
103+
treeRoot.right.left.right.parent = treeRoot.right.left;
104+
105+
System.out.println("LCA of 0 and 7 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.left.right).val);
106+
System.out.println("LCA of 0 and 9 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.right).val);
107+
System.out.println("LCA of 0 and 1 is: " + findLCA(treeRoot.left.left.left, treeRoot.left.left).val);
108+
System.out.println("LCA of 1 and 2 is: " + findLCA(treeRoot.left.left, treeRoot.right.left).val);
109+
System.out.println("LCA of 1 and 7 is: " + findLCA(treeRoot.left.left, treeRoot.right.left.right).val);
110+
System.out.println("LCA of 4 and 7 is: " + findLCA(treeRoot, treeRoot.right.left.right).val);
111+
System.out.println("LCA of 5 and 2 is: " + findLCA(treeRoot.left, treeRoot.right.left).val);
112+
System.out.println("LCA of 7 and 9 is: " + findLCA(treeRoot.right.left.right, treeRoot.right.right).val);
113+
}
114+
}

Diff for: src/main/java/com/ctci/treesandgraphs/Successor.java

+11-11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ private static TreeNode getLeftmostNode(TreeNode node) {
4343
return curr;
4444
}
4545

46+
private static class TreeNode {
47+
int val;
48+
TreeNode parent;
49+
TreeNode left;
50+
TreeNode right;
51+
52+
TreeNode(int val) {
53+
this.val = val;
54+
}
55+
}
56+
4657
public static void main(String[] args) {
4758
/*
4859
The binary search tree looks like:
@@ -84,15 +95,4 @@ public static void main(String[] args) {
8495
System.out.println("InOrder successor of 8 is: " + getInOrderSuccessor(treeRoot.right).val);
8596
System.out.println("InOrder successor of 9 is: " + getInOrderSuccessor(treeRoot.right.right));
8697
}
87-
88-
private static class TreeNode {
89-
int val;
90-
TreeNode parent;
91-
TreeNode left;
92-
TreeNode right;
93-
94-
TreeNode(int val) {
95-
this.val = val;
96-
}
97-
}
9898
}

0 commit comments

Comments
 (0)