Задача: проверить строки на изоморфность
Решаем задачи, которые дают программистам на собеседованиях в IT-компаниях. Сегодня проверяем строки на изоморфность.
Иллюстрация: Polina Vari для Skillbox Media
Сергей Голицын
Senior Java Developer в Covalent Inc. и преподаватель. Больше семи лет в Java-разработке. В свободное время судит хакатоны и делится опытом с начинающими программистами. Пишет статьи для «Хабра» и Medium. Ведёт телеграм-каналы «Полезные ссылки около Java» и Cracking code interview.
Условие. Даны две строки — s и t. Нужно проверить их изоморфность.
Пояснение: строки s и t называются изоморфными, если все вхождения каждого символа строки s можно последовательно заменить другим символом и получить строку t. Порядок символов при этом должен сохраняться, а замена — быть уникальной. Так, два разных символа строки s нельзя заменить одним и тем же символом из строки t, а вот одинаковые символы в строке s должны заменяться одним и тем же символом. Звучит сложно, поэтому просто посмотрите примеры ввода и вывода :)
Ввод и вывод. Пример 1
Ввод и вывод. Пример 2
Ввод и вывод. Пример 3
Решить эту задачу самостоятельно и на разных языках программирования можно на LeetCode. Наше решение взято из Telegram-канала Сергея Cracking code interview.
Решение
Чтобы решить эту задачу, нам нужно создать два массива. Каждый массив мы будем использовать как словарь со всеми возможными символами, которые находятся в ASCII-таблице. Так мы сократим количество вариантов всего до 256 символов и упростим задачу. А вот если бы мы решали её, используя кодировку Unicode, нам бы понадобился массив побольше.
Массивы нужны, чтобы сопоставлять символы из одной строки с символами из другой. Алгоритм работает так:
- Сначала мы создаём два массива и заполняем все элементы значением «–1». Это нужно, чтобы в будущем понять, где у нас незанятые элементы.
- Проходим по символам внутри строк и превращаем каждый символ в ASCII-код — число от 0 до 255. На каждой итерации у нас будет по два таких числа: для строки s и t.
- Затем проверяем, что коды этих символов не заняты в обоих массивах. Если это так, то записываем в первый массив код символа строки t, а во второй — код символа строки s.
- Если один из элементов массива уже занят кодом, значит, строки не будут изоморфными.
Вот как этот алгоритм будет реализован на Java:
Результаты
Временная сложность: O(n) — так как мы перебирали все элементы массива.
Ёмкостная сложность: O(1) — нам нужно определённое количество места в памяти: для двух строк и для двух массивов с символами по 256 байт.