10
10
11
11
Wikipedia link: https://en.wikipedia.org/wiki/Range_minimum_query
12
12
"""
13
+ from math import log2
13
14
14
15
15
16
def build_sparse_table (number_list : list [int ]) -> list [list [int ]]:
@@ -26,27 +27,20 @@ def build_sparse_table(number_list: list[int]) -> list[list[int]]:
26
27
...
27
28
ValueError: empty number list not allowed
28
29
"""
29
- import math
30
-
31
- if number_list == []:
30
+ if not number_list :
32
31
raise ValueError ("empty number list not allowed" )
33
32
34
33
length = len (number_list )
35
- """
36
- Initialise sparse_table
37
-
38
- sparse_table[j][i] represents the minimum value of
39
- the subset of length (2 ** j) of number_list, starting from index i.
40
- """
34
+ # Initialise sparse_table -- sparse_table[j][i] represents the minimum value of the
35
+ # subset of length (2 ** j) of number_list, starting from index i.
41
36
42
37
# smallest power of 2 subset length that fully covers number_list
43
- row = int (math . log2 (length )) + 1
38
+ row = int (log2 (length )) + 1
44
39
sparse_table = [[0 for i in range (length )] for j in range (row )]
45
40
46
41
# minimum of subset of length 1 is that value itself
47
42
for i , value in enumerate (number_list ):
48
43
sparse_table [0 ][i ] = value
49
-
50
44
j = 1
51
45
52
46
# compute the minimum value for all intervals with size (2 ** j)
@@ -58,11 +52,8 @@ def build_sparse_table(number_list: list[int]) -> list[list[int]]:
58
52
sparse_table [j ][i ] = min (
59
53
sparse_table [j - 1 ][i + (1 << (j - 1 ))], sparse_table [j - 1 ][i ]
60
54
)
61
-
62
55
i += 1
63
-
64
56
j += 1
65
-
66
57
return sparse_table
67
58
68
59
@@ -72,37 +63,32 @@ def query(sparse_table: list[list[int]], left_bound: int, right_bound: int) -> i
72
63
0
73
64
>>> query(build_sparse_table([8, 1, 0, 3, 4, 9, 3]), 4, 6)
74
65
3
75
- >>> query(build_sparse_table([8, 1, 0, 3, 4, 9, 3]), 0, 11)
76
- Traceback (most recent call last):
77
- ...
78
- IndexError: list index out of range
79
-
80
66
>>> query(build_sparse_table([3, 1, 9]), 2, 2)
81
67
9
82
68
>>> query(build_sparse_table([3, 1, 9]), 0, 1)
83
69
1
84
-
70
+ >>> query(build_sparse_table([8, 1, 0, 3, 4, 9, 3]), 0, 11)
71
+ Traceback (most recent call last):
72
+ ...
73
+ IndexError: list index out of range
85
74
>>> query(build_sparse_table([]), 0, 0)
86
75
Traceback (most recent call last):
87
76
...
88
77
ValueError: empty number list not allowed
89
78
"""
90
- import math
91
-
92
79
if left_bound < 0 or right_bound >= len (sparse_table [0 ]):
93
80
raise IndexError ("list index out of range" )
94
81
95
82
# highest subset length of power of 2 that is within range [left_bound, right_bound]
96
- j = int (math . log2 (right_bound - left_bound + 1 ))
83
+ j = int (log2 (right_bound - left_bound + 1 ))
97
84
98
- """
99
- minimum of 2 overlapping smaller subsets: [left_bound, left_bound + 2 ** j - 1]
100
- and [right_bound - 2 ** j + 1, right_bound]
101
- """
85
+ # minimum of 2 overlapping smaller subsets:
86
+ # [left_bound, left_bound + 2 ** j - 1] and [right_bound - 2 ** j + 1, right_bound]
102
87
return min (sparse_table [j ][right_bound - (1 << j ) + 1 ], sparse_table [j ][left_bound ])
103
88
104
89
105
90
if __name__ == "__main__" :
106
91
from doctest import testmod
107
92
108
93
testmod ()
94
+ print (f"{ query (build_sparse_table ([3 , 1 , 9 ]), 2 , 2 ) = } " )
0 commit comments