Проверь, что две строки — анаграммы
Задачу на анаграммы дают на скрининге, чтобы посмотреть, как ты работаешь со строками и знаешь ли идиоматичные приёмы Python. Решается в одну строку, но за этой строкой прячется мысль про нормализацию и подсчёт символов — а её как раз и просят проговорить.
Задача
Две строки — анаграммы, если состоят из одних и тех же букв в одинаковом количестве, просто переставленных. Регистр не важен: «Лунь» и «нуль» — анаграммы.
Напиши функцию is_anagram(s1, s2), которая возвращает True, если строки — анаграммы, и False иначе. Проверь на парах: золотарник/разнотолки, Лунь/нуль, Воз/зов, песнь/снедь.
Решение
from collections import Counter
def is_anagram(s1, s2):
return sorted(s1.lower()) == sorted(s2.lower())
def is_anagram_counter(s1, s2):
return Counter(s1.lower()) == Counter(s2.lower())
cases = [
("золотарник", "разнотолки"),
("Лунь", "нуль"),
("Воз", "зов"),
("песнь", "снедь"),
]
for a, b in cases:
r1 = is_anagram(a, b)
r2 = is_anagram_counter(a, b)
print(f"{a!r} и {b!r} -> {r1} (Counter: {r2})")
Разбор
Идея решения простая: если два слова состоят из одинакового набора букв, то после сортировки символов они превратятся в одну и ту же последовательность. sorted('лунь') и sorted('нуль') дают идентичный список букв — значит, анаграммы.
Два обязательных шага, которые легко забыть. Первый — нормализация регистра через .lower(). Без неё «Лунь» и «нуль» не совпадут: заглавная Л и строчная н — разные символы. Собеседующий специально подсовывает пару с разным регистром, чтобы проверить, заметишь ли ты это. Второй — сравнение именно отсортированных последовательностей, а не строк напрямую.
Пара песнь/снедь — контрпример: буквы почти те же, но набор различается (в одном слове п и мягкий знак, в другом д и е), поэтому отсортированные списки не совпадают и функция честно возвращает False. Важно, что решение проверяет не только состав, но и количество каждой буквы: два а в одном слове и одно а в другом дадут разные отсортированные списки.
Альтернатива — collections.Counter. Он строит словарь «буква → сколько раз встретилась», и два таких словаря сравниваются напрямую. По сути та же идея — сравнить состав, — но Counter работает за линейное время O(n), тогда как sorted — за O(n log n). На словах из десятка букв разницы никакой, а на длинных строках Counter предпочтительнее; к тому же он нагляднее выражает намерение «посчитать символы». Хороший ответ на собеседовании — назвать оба подхода и объяснить, почему Counter асимптотически быстрее.
Ещё один способ сжать строку в её «подпись» — RLE-кодирование: другая задача на посимвольный проход, где тоже нужно аккуратно считать повторы.
Ожидаемый результат
'золотарник' и 'разнотолки' -> True (Counter: True)
'Лунь' и 'нуль' -> True (Counter: True)
'Воз' и 'зов' -> True (Counter: True)
'песнь' и 'снедь' -> False (Counter: False)
Хочешь так же уверенно решать на собеседовании?
Читать разбор полезно, а настоящая прокачка — самому решать такие задачи и получать обратную связь. Потренируйся в симуляторе аналитика, лёгкий режим — бесплатно.
Прорешать в бесплатной песочнице