Palindrome Number
Decide whether an integer reads the same forwards and backwards, without converting it to a string.
Open on LeetCode ↗Intuition
Your hand goes straight to str(x) == str(x)[::-1], and the problem specifically asks you not to. That restriction is the whole lesson: once you are forced to work numerically, two facts fall out that the string version hides completely. First, every negative number is a non-palindrome — the minus sign lives only at the front and has no partner at the back, so -121 is out before you touch a digit. Second, you do not need the whole reversal at all. Peel digits off the back of x and push them onto a growing rev, and x shrinks by one digit each time rev grows by one: the moment rev >= x you have crossed the midpoint and half the digits is all you ever needed. That is the invariant — rev always holds the reversed back half and x holds the un-reversed front half, so when they meet you compare them directly (and drop rev's last digit with rev // 10 if the length was odd).
Approach
Reject on shape first
Before any digit work, two whole classes of input are already decided. A negative number can never be a palindrome because the leading minus has no mirror at the other end. And any number ending in 0 — except 0 itself — cannot be one either, because the reversal would need a leading zero, which no integer has. Handling these up front is not just an optimisation; it also protects the main loop, which assumes x is non-negative and does not end in a stray zero.
Reverse only half the digits
Keep two numbers: the shrinking original x and a growing rev. Each turn, take x % 10, append it to rev with rev = rev * 10 + digit, and drop it from x with x //= 10. x loses a digit exactly as rev gains one, so they converge from opposite directions. Loop while x > rev and stop the instant rev catches up — pushing further would just re-reverse ground you already covered, and building the entire reversal is what risks overflow in a fixed-width language.
Compare the halves, allowing for an odd middle
When the loop exits, x is the front half and rev is the reversed back half. If the digit count was even they should be equal outright. If it was odd, rev has swallowed the middle digit — one more than x has — so rev // 10 strips it, and the middle digit is trivially its own mirror. Returning x == rev or x == rev // 10 covers both cases in one line.
Solution & live demo
Edge cases
Return False immediately — the minus sign has no counterpart at the back.
Return False immediately — the reversal would need a leading zero.
Passes the guard (x == 0 is excluded from the trailing-zero rule) and the loop never runs, so 0 == 0 returns True.
rev ends up holding the middle digit; comparing against rev // 10 discards it, since a lone middle digit always mirrors itself.