[
design
binary search
accumulate
]
BinarySearch 0792 Lazy Run-Length Decoding
Problem statement
https://binarysearch.com/problems/Lazy-Run-Length-Decoding/
Solution
First, transform encoded string to pairs (value, letter), then find cumulative sums. Then for value we can use binary search in places. For valueInRange we can use binary search by indexes: for each value use value function.
Complexity
It is O(n) for time. For value it is O(log n). For valueInRange it is O(log n * log M), where M is the maximum range we can have.
Code
class RunLengthDecoder:
def __init__(self, s):
B = ["".join(x) for _, x in groupby(s, key=lambda x: x.isdigit())]
pairs = [[B[2*i+1], int(B[2*i])] for i in range(len(B)//2)]
self.places = [0] + list(accumulate(y for _, y in pairs))
self.letters = [x for x, _ in pairs]
def value(self, i):
idx = bisect.bisect(self.places, i)
return self.letters[idx - 1]
def valueInRange(self, c, i, j):
beg, end = i - 1, j
while beg + 1 < end:
mid = (beg + end)//2
if self.value(mid) < c:
beg = mid
else:
end = mid
return self.value(end) if end < j else "?"
Remark
Notice, that alternative way for valueInRange is to keep places for each letter, then complexity will be O(26 * log n), which works similar in this problem, but for other constraints can be different.