Напиши функцию, которая проверяет, является ли число палиндромом без преобразования в строку
Что проверяют
Сообразите ли вы развернуть число арифметикой и обработаете ли краевые случаи.
Как отвечать
Идея: разворачивать число, отделяя последнюю цифру остатком от деления на десять и приписывая её к результату.
Сначала отсеките краевые случаи:
- отрицательные не палиндромы из-за знака;
- кратные десяти, кроме нуля, не палиндромы: последняя цифра ноль, а первая нулём быть не может.
function isPalindrome(x) {
if (x < 0 || (x % 10 === 0 && x !== 0)) return false;
let reversed = 0;
while (x > reversed) {
reversed = reversed * 10 + (x % 10);
x = Math.floor(x / 10);
}
// чётное число цифр: x === reversed
// нечётное: средняя цифра лишняя, отбрасываем её
return x === reversed || x === Math.floor(reversed / 10);
}Ключевой приём это разворот только половины числа. Цикл идёт, пока оставшаяся часть больше развёрнутой, то есть примерно до середины. Это вдвое меньше итераций и, что важнее, исключает переполнение: полный разворот большого числа может выйти за пределы типа, а половина точно помещается. В JavaScript переполнение начинается за пределом безопасных целых, в языках с фиксированным целым проблема возникает раньше.
Разбор нечётного случая: у числа 12321 в конце получится x равное 12, а reversed равное 123. Средняя цифра оказалась в развёрнутой части, поэтому её отбрасывают делением на десять.
Сложность: время пропорционально числу цифр, то есть логарифм от значения, память постоянная.
Проверьте на примерах: ноль это палиндром, однозначные числа палиндромы, 10 нет, 1221 да, 12321 да.
Где спотыкаются
Разворачивают число целиком и получают переполнение.
Забывают про отрицательные числа.
Не обрабатывают числа, оканчивающиеся нулём.
Ошибаются в нечётном случае и не отбрасывают среднюю цифру.