Проверка строки на палиндром
Условие
Напишите функцию isPalindrome(str), которая проверяет, является ли строка палиндромом.
Требования
- Палиндром читается одинаково слева направо и справа налево
- Игнорировать регистр букв
- Игнорировать пробелы и знаки пунктуации
- Учитывать только буквы и цифры
Примеры
isPalindrome("racecar"); // true
isPalindrome("A man a plan a canal Panama"); // true
isPalindrome("hello"); // false
isPalindrome("Was it a car or a cat I saw?"); // true
isPalindrome(""); // true
isPalindrome("12321"); // true
Бонус
Решите задачу без создания дополнительной строки (in-place с двумя указателями).
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Задача на проверку палиндрома — классическая в собеседованиях. Требует понимания строк, регулярных выражений и оптимизации по памяти.
Базовое решение
Сначала решим задачу стандартным способом:
function isPalindrome(str: string): boolean {
// Удаляем все символы, кроме букв и цифр
// Преобразуем в нижний регистр
const cleaned = str
.toLowerCase()
.replace(/[^a-z0-9]/g, "");
// Проверяем, совпадает ли строка с обратной версией
return cleaned === cleaned.split("").reverse().join("");
}
Анализ:
toLowerCase()— игнорируем регистрreplace(/[^a-z0-9]/g, "")— убираем всё кроме букв и цифр- Сравниваем исходную с перевёрнутой версией
- Временная сложность: O(n), пространственная: O(n) (создаём новую строку)
Оптимизированное решение (два указателя)
Для бонуса решим без создания дополнительной строки:
function isPalindromeTwoPointers(str: string): boolean {
// Вспомогательная функция для проверки буквы/цифры
const isAlphaNumeric = (char: string): boolean => {
const code = char.charCodeAt(0);
return (code >= 48 && code <= 57) || // 0-9
(code >= 97 && code <= 122) || // a-z
(code >= 65 && code <= 90); // A-Z
};
let left = 0;
let right = str.length - 1;
while (left < right) {
// Пропускаем символы, которые не буквы/цифры (левый указатель)
while (left < right && !isAlphaNumeric(str[left])) {
left++;
}
// Пропускаем символы, которые не буквы/цифры (правый указатель)
while (left < right && !isAlphaNumeric(str[right])) {
right--;
}
// Сравниваем символы (игнорируя регистр)
if (str[left].toLowerCase() !== str[right].toLowerCase()) {
return false;
}
left++;
right--;
}
return true;
}
Анализ оптимизированного решения:
- Используем два указателя:
leftс начала,rightс конца - Пропускаем символы, которые не подходят под условия
- Сравниваем символы в нижнем регистре
- Временная сложность: O(n), пространственная: O(1) (константа)
Альтернатива с регулярными выражениями
Можно использовать более компактный вариант:
function isPalindromeCompact(str: string): boolean {
const cleaned = str.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
return cleaned === cleaned.split("").reverse().join("");
}
Это эквивалентно первому решению, просто более компактно.
Примеры использования
console.log(isPalindrome("racecar")); // true
console.log(isPalindrome("A man a plan a canal Panama")); // true
console.log(isPalindrome("hello")); // false
console.log(isPalindrome("Was it a car or a cat I saw?")); // true
console.log(isPalindrome("")); // true
console.log(isPalindrome("12321")); // true
Рекомендации для собеседования
- Начните с простого решения — оно более читаемо
- Спросите про оптимизацию — это покажет понимание сложности
- Обсудите граничные случаи — пустая строка, одна буква, только пробелы
- Выберите правильный язык — TypeScript показывает профессионализм
- Объясните трейд-офф — простота vs оптимизация памяти
Для собеседования лучше показать оба решения: сначала простое (O(n) memory), потом объяснить, как его оптимизировать (O(1) memory). Это демонстрирует аналитическое мышление и заботу о производительности.