20
20
21
21
public class LowestCommonAncestorEulerTour {
22
22
23
+ public static void main (String [] args ) {
24
+ TreeNode root = createFirstTreeFromSlides ();
25
+ LowestCommonAncestorEulerTour solver = new LowestCommonAncestorEulerTour (root );
26
+
27
+ // LCA of 13 and 14 = 2
28
+ TreeNode lca = solver .lca (13 , 14 );
29
+ System .out .printf ("LCA of 13 and 14 = %s\n " , lca );
30
+ if (lca .index () != 2 ) {
31
+ System .out .println ("Error, expected lca to be 2" );
32
+ }
33
+
34
+ // LCA of 9 and 11 = 0
35
+ lca = solver .lca (9 , 11 );
36
+ System .out .printf ("LCA of 9 and 11 = %s\n " , lca );
37
+ if (lca .index () != 0 ) {
38
+ System .out .println ("Error, expected lca to be 0" );
39
+ }
40
+
41
+ // LCA of 12 and 12 = 12
42
+ lca = solver .lca (12 , 12 );
43
+ System .out .printf ("LCA of 12 and 12 = %s\n " , lca );
44
+ if (lca .index () != 12 ) {
45
+ System .out .println ("Error, expected lca to be 12" );
46
+ }
47
+ }
48
+
49
+ private static TreeNode createFirstTreeFromSlides () {
50
+ int n = 17 ;
51
+ List <List <Integer >> tree = createEmptyGraph (n );
52
+
53
+ addUndirectedEdge (tree , 0 , 1 );
54
+ addUndirectedEdge (tree , 0 , 2 );
55
+ addUndirectedEdge (tree , 1 , 3 );
56
+ addUndirectedEdge (tree , 1 , 4 );
57
+ addUndirectedEdge (tree , 2 , 5 );
58
+ addUndirectedEdge (tree , 2 , 6 );
59
+ addUndirectedEdge (tree , 2 , 7 );
60
+ addUndirectedEdge (tree , 3 , 8 );
61
+ addUndirectedEdge (tree , 3 , 9 );
62
+ addUndirectedEdge (tree , 5 , 10 );
63
+ addUndirectedEdge (tree , 5 , 11 );
64
+ addUndirectedEdge (tree , 7 , 12 );
65
+ addUndirectedEdge (tree , 7 , 13 );
66
+ addUndirectedEdge (tree , 11 , 14 );
67
+ addUndirectedEdge (tree , 11 , 15 );
68
+ addUndirectedEdge (tree , 11 , 16 );
69
+
70
+ return TreeNode .rootTree (tree , 0 );
71
+ }
72
+
73
+ /* Graph/Tree creation helper methods. */
74
+
75
+ // Create a graph as a adjacency list with 'n' nodes.
76
+ public static List <List <Integer >> createEmptyGraph (int n ) {
77
+ List <List <Integer >> graph = new ArrayList <>(n );
78
+ for (int i = 0 ; i < n ; i ++) graph .add (new LinkedList <>());
79
+ return graph ;
80
+ }
81
+
82
+ public static void addUndirectedEdge (List <List <Integer >> graph , int from , int to ) {
83
+ graph .get (from ).add (to );
84
+ graph .get (to ).add (from );
85
+ }
86
+
23
87
public static class TreeNode {
24
88
// Number of nodes in the subtree. Computed when tree is built.
25
89
private int n ;
@@ -138,13 +202,6 @@ private void preprocess() {
138
202
sparseTable = new MinSparseTable (nodeDepth );
139
203
}
140
204
141
- private void visit (TreeNode node , long depth ) {
142
- nodeOrder [tourIndex ] = node ;
143
- nodeDepth [tourIndex ] = depth ;
144
- last [node .index ()] = tourIndex ;
145
- tourIndex ++;
146
- }
147
-
148
205
// Construct Euler Tour by populating the 'depth' and 'nodeOrder' arrays.
149
206
private void dfs (TreeNode node , long depth ) {
150
207
if (node == null ) {
@@ -158,6 +215,13 @@ private void dfs(TreeNode node, long depth) {
158
215
}
159
216
}
160
217
218
+ private void visit (TreeNode node , long depth ) {
219
+ nodeOrder [tourIndex ] = node ;
220
+ nodeDepth [tourIndex ] = depth ;
221
+ last [node .index ()] = tourIndex ;
222
+ tourIndex ++;
223
+ }
224
+
161
225
// Finds the lowest common ancestor of the nodes id1 and id2.
162
226
public TreeNode lca (int id1 , int id2 ) {
163
227
// Lazily preprocess here instead of in constructor.
@@ -241,102 +305,4 @@ public int queryIndex(int l, int r) {
241
305
}
242
306
}
243
307
244
- /* Graph/Tree creation helper methods. */
245
-
246
- // Create a graph as a adjacency list with 'n' nodes.
247
- public static List <List <Integer >> createEmptyGraph (int n ) {
248
- List <List <Integer >> graph = new ArrayList <>(n );
249
- for (int i = 0 ; i < n ; i ++) graph .add (new LinkedList <>());
250
- return graph ;
251
- }
252
-
253
- public static void addUndirectedEdge (List <List <Integer >> graph , int from , int to ) {
254
- graph .get (from ).add (to );
255
- graph .get (to ).add (from );
256
- }
257
-
258
- /* Example usage: */
259
-
260
- public static void main (String [] args ) {
261
- // example1();
262
- example2 ();
263
- }
264
-
265
- private static TreeNode createFirstTreeFromSlides () {
266
- int n = 17 ;
267
- List <List <Integer >> tree = createEmptyGraph (n );
268
-
269
- addUndirectedEdge (tree , 0 , 1 );
270
- addUndirectedEdge (tree , 0 , 2 );
271
- addUndirectedEdge (tree , 1 , 3 );
272
- addUndirectedEdge (tree , 1 , 4 );
273
- addUndirectedEdge (tree , 2 , 5 );
274
- addUndirectedEdge (tree , 2 , 6 );
275
- addUndirectedEdge (tree , 2 , 7 );
276
- addUndirectedEdge (tree , 3 , 8 );
277
- addUndirectedEdge (tree , 3 , 9 );
278
- addUndirectedEdge (tree , 5 , 10 );
279
- addUndirectedEdge (tree , 5 , 11 );
280
- addUndirectedEdge (tree , 7 , 12 );
281
- addUndirectedEdge (tree , 7 , 13 );
282
- addUndirectedEdge (tree , 11 , 14 );
283
- addUndirectedEdge (tree , 11 , 15 );
284
- addUndirectedEdge (tree , 11 , 16 );
285
-
286
- return TreeNode .rootTree (tree , 0 );
287
- }
288
-
289
- private static TreeNode createTreeFromSlides () {
290
- int n = 7 ;
291
- List <List <Integer >> tree = createEmptyGraph (n );
292
-
293
- addUndirectedEdge (tree , 0 , 1 );
294
- addUndirectedEdge (tree , 0 , 2 );
295
- addUndirectedEdge (tree , 1 , 3 );
296
- addUndirectedEdge (tree , 2 , 4 );
297
- addUndirectedEdge (tree , 2 , 5 );
298
- addUndirectedEdge (tree , 4 , 6 );
299
-
300
- return TreeNode .rootTree (tree , 0 );
301
- }
302
-
303
- private static void example2 () {
304
- TreeNode root = createTreeFromSlides ();
305
- LowestCommonAncestorEulerTour solver = new LowestCommonAncestorEulerTour (root );
306
-
307
- TreeNode lca = solver .lca (6 , 5 );
308
- System .out .printf ("LCA of 6 and 5 = %s\n " , lca );
309
-
310
- System .out .println (java .util .Arrays .toString (solver .nodeDepth ));
311
- System .out .println (java .util .Arrays .toString (solver .nodeOrder ));
312
- System .out .println (java .util .Arrays .toString (solver .last ));
313
- }
314
-
315
- private static void example1 () {
316
- // Prints:
317
- // LCA of 10 and 15 = 5
318
- // LCA of 13 and 14 = 2
319
- // LCA of 9 and 11 = 0
320
-
321
- TreeNode root = createFirstTreeFromSlides ();
322
- LowestCommonAncestorEulerTour solver = new LowestCommonAncestorEulerTour (root );
323
-
324
- TreeNode lca = solver .lca (10 , 15 );
325
- System .out .printf ("LCA of 10 and 15 = %s\n " , lca );
326
- if (lca .index () != 5 ) {
327
- System .out .println ("Error, expected lca to be 5" );
328
- }
329
-
330
- lca = solver .lca (13 , 14 );
331
- System .out .printf ("LCA of 13 and 14 = %s\n " , lca );
332
- if (lca .index () != 2 ) {
333
- System .out .println ("Error, expected lca to be 2" );
334
- }
335
-
336
- lca = solver .lca (9 , 11 );
337
- System .out .printf ("LCA of 9 and 11 = %s\n " , lca );
338
- if (lca .index () != 0 ) {
339
- System .out .println ("Error, expected lca to be 0" );
340
- }
341
- }
342
308
}
0 commit comments