ENIGMA AI
ENIGMA AI

Как проверить, является ли строка палиндромом?

встречается 5× junior algorithms

Как ответить

Палиндром — строка, которая читается одинаково слева направо и справа налево. Самый простой способ — развернуть строку и сравнить: s == s[::-1] в Python. На собеседовании от junior-разработчика обычно ждут два подхода: через реверс и через два указателя. Важно обсудить, как учитывать регистр, пробелы и знаки препинания — это часто является частью задачи.

  • Подход 1: разворот строки. В Python s[::-1] создаёт новую строку за O(n) памяти. Встроенный reverse в C#/Java даёт такую же сложность. Минус: для длинных строк тратится лишняя память.
  • Подход 2: два указателя. Ставим left = 0, right = len(s)-1. Сравниваем символы, двигаем указатели навстречу, пока left < right. Преимущество: O(1) дополнительной памяти, O(n) времени. Если нужен case-insensitive — приводим символы к одному регистру перед сравнением.
  • Фильтрация лишних символов. Если условие «только буквы и цифры» (как в LeetCode 125), то при движении указателей пропускаем неалфавитно-цифровые символы. Для этого можно использовать char.IsLetterOrDigit(c) в C# или c.isalnum() в Python.
  • Граничные случаи. Пустая строка и строка из одного символа — палиндромы. null лучше обрабатывать отдельно — выбросить исключение или вернуть false в зависимости от контекста.
  • Сложность. Идеальное решение — O(n) времени и O(1) памяти. Реверс даёт O(n) по памяти, что тоже принимается, но вопрос про оптимизацию всплывёт.

Пример реализации на Python (два указателя, без фильтрации):

def is_palindrome(s: str) -> bool:
    left, right = 0, len(s) - 1
    while left < right:
        if s[left].lower() != s[right].lower():
            return False
        left += 1
        right -= 1
    return True

Для варианта с фильтрацией добавляем пропуск:

def is_palindrome(s: str) -> bool:
    left, right = 0, len(s) - 1
    while left < right:
        while left < right and not s[left].isalnum():
            left += 1
        while left < right and not s[right].isalnum():
            right -= 1
        if s[left].lower() != s[right].lower():
            return False
        left += 1
        right -= 1
    return True

Ключевые тезисы

  • Простейшее решение: сравнить строку с её обратной копией (s == s[::-1]) — O(n) времени и O(n) памяти.
  • Оптимальное решение: два указателя с разных концов — O(n) времени, O(1) памяти.
  • Обязательно учитывать регистр (lower()/casefold()) и игнорировать небуквенно-цифровые символы, если это требуется.
  • Граничные случаи: пустая строка, один символ, строка из пробелов — все являются палиндромами.
  • Для чисел палиндром можно проверять без преобразования в строку: перевернуть половину числа и сравнить.

Что спросят дальше

  • — Как модифицировать решение, чтобы игнорировать всё, кроме букв и цифр? Напиши код.
  • — Как найти самую длинную палиндромную подстроку в строке? Какая сложность у наивного алгоритма?
  • — Можно ли проверить палиндром рекурсивно? Какие будут ограничения по стеку?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение