Задача со сжатием строки RLE не проходит по памяти и по времени
пишу код под задачу. Краткое описание задачи: Подается строка s в RLE виде. Назовём строку, из которой была получена s строкой t. Вам даны q запросов, каждый из них представлен целыми числами l и r. В каждом запросе вам необходимо найти длину сжатой подстроки t[l...r]. Выведите q чисел, каждое в отдельной строке — ответы на запросы в том порядке, в котором запросы были заданы во входных данных.
x1000000000yz
3
2 1000000001
2 1000000002
5938493 15938493
Собственно я ее решил, но памяти и по времени не проходит Вот мой код решения:
def encode(data):
encoding = ''
prev_char = ''
count = 1
for char in data:
if char != prev_char:
if prev_char and count == 1:
encoding += prev_char
elif prev_char:
encoding += str(count) + prev_char
count = 1
prev_char = char
else:
count += 1
else:
if count == 1:
encoding += prev_char
else:
encoding += str(count) + prev_char
return encoding
def decode(data):
decode = ''
prev_char = ''
count = ''
for char in data:
if char.isdigit():
count += char
elif char.isalpha() and count == '':
decode += char
else:
decode += char * int(count)
count = ''
return decode
s = input()
numbers = [input().split() for _ in range(int(input()))]
n = decode(s)
for i in numbers:
print(len(encode(n[int(i[0])-1:int(i[1])])))
Я еще новичок в программировании. Прошу помочь с оптимизацией, может посмотреть что-нибудь и переписать по-новому. Любую помощь.
Ответы (1 шт):
Похоже, вы строите всю исходную строку t
Вместо этого стоит построить набор отрезков, для каждого из которых указывается позиция начала и длина (или конец, если это будет удобнее), а также длину RLE для данного отрезка, а лучше накопленную длину RLE (от начала до текущего отрезка)
Для каждого запроса:
- бинарным поиском (точное условие с ограничениями вы не привели, может хватить и линейного поиска) находите отрезок, содержащий начало, вычисляете, сколько этого отрезка захвачено, строите соотв. RLE
- ищете отрезок, содержащий конец, вычисляете, сколько этого отрезка захвачено, строите соотв. RLE
- добавляете длины RLE для всех промежуточных отрезков - это легко сделать, вычислив разность накопленных длин RLE
Сложность получается O(N+QlgN), где N - длина s, оно же пропорционально количеству отрезков, Q - количество запросов
Пример:
t=xxxyyyyyyyyyyyyyyyzzzzaa
s = 3x15y4z2a
3x 15y 4z 2a
char x y z a //только для справки, в решении не нужен
start 1 4 19 23
len 3 15 4 2 //на самом деле тоже можно не хранить, а смотреть разницу со следующим
cumRLE 0 2 5 7
Запрос 2,21 захватывает часть первого отрезка длиной 2, т.е. 2x - даёт вклад 2, часть третьего отрезка с длиной 3, 3z - тоже вклад 2, и от прмежуточных вклад 5-2=3, итого 7
Проверочка:
| |
xxxyyyyyyyyyyyyyyyzzzzaa
xxyyyyyyyyyyyyyyyzzz
2x15y3z
длина 7
