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

«Как в Dart определить, является ли строка палиндромом?» — вопрос из категории Алгоритмы и структуры данных, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для проверки строки на палиндром нужно сравнить её с перевёрнутой версией. Важно предварительно нормализовать строку: удалить незначительные символы (пробелы, знаки препинания) и привести к единому регистру, если проверка должна быть регистронезависимой.

Эффективное решение с использованием двух указателей: Этот подход работает за O(n) и требует O(1) дополнительной памяти, так как не создаёт новых строк для разворота.

bool isPalindrome(String input) {
  // Нормализация: убираем пробелы, приводим к нижнему регистру.
  // Можно расширить replaceAll для удаления знаков препинания.
  final normalized = input.replaceAll(RegExp(r's+'), '').toLowerCase();

  int left = 0;
  int right = normalized.length - 1;

  while (left < right) {
    if (normalized[left] != normalized[right]) {
      return false;
    }
    left++;
    right--;
  }
  return true;
}

void main() {
  print(isPalindrome('А роза упала на лапу Азора')); // true
  print(isPalindrome('Hello')); // false
  print(isPalindrome('racecar')); // true
}

Альтернативное, более декларативное решение (менее эффективное по памяти):

bool isPalindromeSimple(String input) {
  final normalized = input.replaceAll(RegExp(r's+'), '').toLowerCase();
  return normalized == normalized.split('').reversed.join();
  // split('') и join() создают новые объекты List и String.
}

Ключевые моменты:

  • RegExp(r's+') удаляет все пробельные символы (пробелы, табуляции, переносы строк).
  • Метод toLowerCase() обеспечивает регистронезависимое сравнение.
  • Первый алгоритм с двумя указателями предпочтительнее для потенциально очень длинных строк.