Как обрабатывать средний элемент строки при проверке палиндрома
Что проверяют
Понимаете ли вы, что средний символ строки нечётной длины сравнивать не нужно, и умеете ли показать это условием цикла, а не отдельной веткой if. Следом просят решить задачу без создания новой строки и с игнорированием регистра, пробелов и знаков.
Как отвечать
Базовое решение на двух указателях: left = 0, right = s.lastIndex, цикл while (left < right). Строгое условие и есть ответ про середину:
- нечётная длина: у
"level"указатели сойдутся на индексе 2,left == right, и цикл завершится. Символ сам с собой всегда совпадает, отдельная обработка не нужна; - чётная длина: у
"abba"после сравнения индексов 1 и 2 указатели разойдутся, центрального символа нет вовсе; - сложность: сравнений ровно
n / 2с целочисленным делением, O(n) по времени и O(1) по памяти; - вариант через индекс:
for (i in 0 until s.length / 2)со сравнениемs[i]иs[s.length - 1 - i]. Тот же приём: деление с округлением вниз само отбрасывает середину.
Если нужно игнорировать пробелы и знаки препинания, не создавайте очищенную копию. Сдвигайте указатели, пропуская символы, для которых isLetterOrDigit() возвращает false, а сравнивайте через lowercaseChar() или equals(other, ignoreCase = true). Метод toLowerCase() в Kotlin устарел, актуальны lowercase() и lowercaseChar().
Для Android-разработчика плюсом будет Юникод: эмодзи и часть иероглифов занимают два Char (суррогатную пару), и посимвольное сравнение с конца такую строку ломает. Если это важно, работайте с кодовыми точками через codePointAt или с графемами через BreakIterator.
Где спотыкаются
Добавляют отдельную ветку для нечётной длины или вырезают средний символ через substring. Код усложняется, создаются лишние строки, а смысл строгого < так и остаётся непонятым.
Ошибаются на единицу: берут right = s.length и получают StringIndexOutOfBoundsException на первом же сравнении.
Чистят строку регуляркой по пробелам, как replace("\\s".toRegex(), ""). Запятые и точки остаются, и фраза «A man, a plan, a canal: Panama» уже не проходит проверку.