@@ -23,24 +23,24 @@ def swap(a: int, b: int) -> tuple[int, int]:
23
23
24
24
25
25
def create_sparse (max_node : int , parent : list [list [int ]]) -> list [list [int ]]:
26
- """
26
+ r """
27
27
Create a sparse table that saves each node's 2^i-th parent.
28
-
29
- The given ``parent`` table should have the direct parent of each node in row 0.
30
- This function fills in:
31
-
28
+
29
+ The given ``parent`` table should have the direct parent of each node
30
+ in row 0. This function fills in:
31
+
32
32
parent[j][i] = parent[j - 1][parent[j - 1][i]]
33
-
33
+
34
34
for each j where 2^j is less than max_node.
35
-
35
+
36
36
For example, consider a small tree where:
37
37
- Node 1 is the root (its parent is 0),
38
38
- Nodes 2 and 3 have parent 1.
39
-
39
+
40
40
We set up the parent table for only two levels (row 0 and row 1)
41
41
for max_node = 3. (Note that in practice the table has many rows.)
42
-
43
- >>> parent0 = [0, 0, 1, 1] # 0 is unused; node1's parent=0, nodes 2 and 3's parent=1.
42
+
43
+ >>> parent0 = [0, 0, 1, 1]
44
44
>>> parent1 = [0, 0, 0, 0]
45
45
>>> parent = [parent0, parent1]
46
46
>>> sparse = create_sparse(3, parent)
@@ -59,18 +59,17 @@ def create_sparse(max_node: int, parent: list[list[int]]) -> list[list[int]]:
59
59
def lowest_common_ancestor (
60
60
u : int , v : int , level : list [int ], parent : list [list [int ]]
61
61
) -> int :
62
- """
62
+ r """
63
63
Return the lowest common ancestor (LCA) of nodes u and v in a tree.
64
-
65
- The lists ``level`` and ``parent`` must be precomputed. ``level[i]`` is the depth
66
- of node i, and ``parent`` is a sparse table where parent[0][i] is the direct parent
67
- of node i.
68
-
64
+
65
+ The lists ``level`` and ``parent`` must be precomputed.
66
+
69
67
>>> # Consider a simple tree:
70
68
>>> # 1
71
69
>>> # / \\
72
70
>>> # 2 3
73
- >>> # With levels: level[1]=0, level[2]=1, level[3]=1 and parent[0]=[0, 0, 1, 1]
71
+ >>> # With levels: level[1]=0, level[2]=1, level[3]=1 and
72
+ >>> # parent[0]=[0, 0, 1, 1]
74
73
>>> level = [-1, 0, 1, 1] # index 0 is dummy
75
74
>>> parent = [[0, 0, 1, 1]] + [[0, 0, 0, 0] for _ in range(19)]
76
75
>>> lowest_common_ancestor(2, 3, level, parent)
@@ -104,20 +103,20 @@ def breadth_first_search(
104
103
graph : dict [int , list [int ]],
105
104
root : int = 1 ,
106
105
) -> tuple [list [int ], list [list [int ]]]:
107
- """
106
+ r """
108
107
Run a breadth-first search (BFS) from the root node of the tree.
109
-
108
+
110
109
This sets each node's direct parent (stored in parent[0]) and calculates the
111
110
depth (level) of each node from the root.
112
-
111
+
113
112
>>> # Consider a simple tree:
114
113
>>> # 1
115
114
>>> # / \\
116
115
>>> # 2 3
117
116
>>> graph = {1: [2, 3], 2: [], 3: []}
118
117
>>> level = [-1] * 4 # index 0 is unused; nodes 1 to 3.
119
118
>>> parent = [[0] * 4 for _ in range(20)]
120
- >>> new_level, new_parent = breadth_first_search(level, parent, 3, graph, root=1)
119
+ >>> new_level, new_parent= breadth_first_search(level,parent,3, graph,root=1)
121
120
>>> new_level[1:4]
122
121
[0, 1, 1]
123
122
>>> new_parent[0][1:4]
@@ -137,30 +136,30 @@ def breadth_first_search(
137
136
138
137
139
138
def main () -> None :
140
- """
139
+ r """
141
140
Run a BFS to set node depths and parents in a sample tree, then create the
142
141
sparse table and compute several lowest common ancestors.
143
-
142
+
144
143
The sample tree used is:
145
-
144
+
146
145
1
147
146
/ | \
148
147
2 3 4
149
148
/ / \\ \\
150
149
5 6 7 8
151
150
/ \\ | / \\
152
151
9 10 11 12 13
153
-
152
+
154
153
The expected lowest common ancestors are:
155
154
- LCA(1, 3) --> 1
156
155
- LCA(5, 6) --> 1
157
156
- LCA(7, 11) --> 3
158
157
- LCA(6, 7) --> 3
159
158
- LCA(4, 12) --> 4
160
159
- LCA(8, 8) --> 8
161
-
160
+
162
161
To test main() without it printing to the console, we capture the output.
163
-
162
+
164
163
>>> import sys
165
164
>>> from io import StringIO
166
165
>>> backup = sys.stdout
0 commit comments