Как сравнивать цифры с начала и конца для проверки палиндрома?
Что проверяют
Базовое владение Python и умение не остановиться на однострочнике. s == s[::-1] интервьюер примет, но следом попросит два указателя без копии строки или решение вовсе без перевода числа в строку.
Как отвечать
Покажите три уровня:
- однострочник:
str(n) == str(n)[::-1]. O(k) по времени, где k число цифр, и O(k) памяти на копию. Читаемо, в рабочем коде обычно этого достаточно; - два указателя:
left, right = 0, len(s)-1, покаleft < rightсравниваемs[left]иs[right], при расхождении сразуreturn False, иначе сдвигаем оба к центру. Копии нет, выход при первом несовпадении; - без строки: разворачиваем половину цифр через
divmod:x, d = divmod(x, 10), затемrev = rev * 10 + d, покаx > rev. В концеx == rev or x == rev // 10. Отрицательные и оканчивающиеся на 0, кроме самого 0, отсекаются заранее.
Переполнения в Python нет, int произвольной длины, поэтому развернуть можно и всё число. Довод в пользу половины здесь другой: вдвое меньше итераций. Для огромных чисел учтите, что в актуальных версиях str(n) у числа длиннее 4300 цифр выбрасывает ValueError, лимит меняется через sys.set_int_max_str_digits.
Если на входе строка, уточните правила очистки: "".join(ch.lower() for ch in s if ch.isalnum()). Удаление одних пробелов через split() оставляет знаки препинания, и фраза «Was it a car or a cat I saw?» перестаёт быть палиндромом.
Тесты удобно собрать через pytest.mark.parametrize: 0, 7, 10, 121, 1221, -121.
Где спотыкаются
Пишут reversed(s) == s и всегда получают False: reversed возвращает итератор, а не строку.
Разворачивают половину числа без проверки нуля на конце, и 10 признаётся палиндромом.
Решают рекурсией is_pal(s[1:-1]). Каждый срез копирует строку, выходит O(k²), а на длинной строке рекурсия упирается в лимит глубины, по умолчанию 1000 вызовов.