Задачи по Python с собеседований
Python·middle

Сожми строку RLE-кодированием

RLE (run-length encoding) — задача на скрининге уровня middle: проверяют, аккуратно ли ты держишь состояние в цикле и не забываешь ли про краевые случаи. Алгоритм наивно простой, но именно на краях люди и спотыкаются — последняя серия символов теряется чаще всего.

Задача

RLE-кодирование сжимает подряд идущие одинаковые символы в пару «сколько раз + сам символ». Например, WWWWWWWWW превращается в 9W.

Напиши функцию rle_encode(s), которая кодирует строку. Проверь на:

  • 'WWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW''9W3B24W1B14W'
  • 'ABCABCABCDDDFFFFFF''1A1B1C1A1B1C1A1B1C3D6F'

Решение

def rle_encode(s):
    if not s:
        return ""
    count = 1
    result = ""
    for i in range(len(s) - 1):
        if s[i] == s[i + 1]:
            count += 1
        else:
            result += str(count) + s[i]
            count = 1
    result += str(count) + s[-1]
    return result


cases = [
    "WWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW",
    "ABCABCABCDDDFFFFFF",
    "AAAA",
    "",
]
for s in cases:
    print(f"{s!r} -> {rle_encode(s)!r}")

Разбор

Идея — идти по строке и копить счётчик, пока текущий символ совпадает со следующим. Как только сосед отличается — серия закончилась: дописываем в результат «счётчик + символ» и сбрасываем счётчик в единицу.

Ключевой приём — сравнивать не «текущий с предыдущим», а s[i] c s[i + 1]. Поэтому цикл идёт до len(s) - 1: у последнего символа нет соседа справа, обращение к s[i + 1] вышло бы за границу. Это и есть первая ловушка.

Вторая, самая частая, — потерянная последняя серия. Внутри цикла мы дописываем серию только в момент смены символа. Но у последней серии смены не происходит — строка просто кончается. Поэтому после цикла обязательна строка result += str(count) + s[-1], которая закрывает хвост. Убери её — и '9W3B24W1B14W' превратится в '9W3B24W1B', потеряв финальные 14W. На собеседовании прогон именно последней серии в голове — то, что отличает аккуратное решение от «вроде работает».

Третья ловушка — пустая строка. Без охраны if not s строка s[-1] в конце упадёт с IndexError, ведь брать последний символ не из чего. Одна проверка в начале закрывает этот случай — возвращаем пустую строку. Собеседующий любит спросить «а что на пустом входе?», и готовый ответ тут ценится.

По формату вывода: владелец ноутбука кодирует как «число, потом буква» (9W), поэтому 'ABC...' даёт '1A1B1C...' — одиночные символы тоже получают счётчик 1. Это делает кодирование однозначно обратимым, хотя для строк без повторов RLE, наоборот, раздувает длину — что тоже стоит проговорить: сжатие выгодно только на данных с длинными сериями.

Сложность — O(n): один проход по строке. Родственная задача на посимвольный разбор — проверка анаграмм, где вместо серий считают общий состав букв.

Ожидаемый результат

'WWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW' -> '9W3B24W1B14W'
'ABCABCABCDDDFFFFFF' -> '1A1B1C1A1B1C1A1B1C3D6F'
'AAAA' -> '4A'
'' -> ''

Хочешь так же уверенно решать на собеседовании?

Читать разбор полезно, а настоящая прокачка — самому решать такие задачи и получать обратную связь. Потренируйся в симуляторе аналитика, лёгкий режим — бесплатно.

Прорешать в бесплатной песочнице

Смежные задачи

Вопросы по теме

Из блога