LeetCode #9 Easy

Palindrome Number

Palindrome Number: decide whether an integer reads the same forwards and backwards, without converting it to a string.

Constraints
  • -2³¹ <= x <= 2³¹ - 1
mathtwo-pointers
Open on LeetCode ↗
02

Intuition

For palindrome number 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).

How to spot this pattern

Reverse only half the digits and compare. Stopping when x > rev fails means you've crossed the midpoint, which avoids the overflow that reversing the whole number risks — and makes the string conversion the problem forbids unnecessary.

03

Approach

Try it first

Before reading on: price up what the direct approach costs here, then ask what pattern in the numbers removes the loop entirely. Aim for O(log n) time and O(1) space.

1

Reject on shape first

Two classes of input are decided before any digit work. A negative number cannot be a palindrome, since the leading minus has no mirror. And any number ending in 0, except 0 itself, cannot be either, because the reversal would need a leading zero. Handling these up front is not just an optimisation — it protects the main loop, which assumes x is non-negative with no trailing zero.

2

Reverse only half the digits

Keep the shrinking original x and a growing rev. Each turn take x % 10, append it with rev = rev * 10 + digit, and drop it with x //= 10, so x loses a digit exactly as rev gains one and they converge from opposite ends. Loop while x > rev and stop the instant rev catches up — going further re-covers ground, and building the whole reversal is what risks overflow in a fixed-width language.

3

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.

04

Solution & live demo

▶1class Solution:
▶2 def isPalindrome(self, x:
▶3 int) -> bool:
▶4 if x < 0 or (x % 10 == 0 and x != 0):
▶5 return False
▶6 rev = 0
▶7 while x > rev:
▶8 rev = rev * 10 + x % 10
▶9 x //= 10
▶10 return x == rev or x == rev // 10
05

Common pitfalls

Not handling trailing zeros

✗ Wrong
if x < 0: return False
✓ Right
if x < 0 or (x % 10 == 0 and x != 0):
    return False

A number ending in 0 would need to start with 0 to be a palindrome, which no valid integer does. Without the guard, 10 reverses to 1 and compares equal after the halving logic.

Ignoring the odd-length midpoint

✗ Wrong
return x == rev
✓ Right
return x == rev or x == rev // 10

With an odd digit count the middle digit ends up in rev but not in x — for 121 the loop leaves x = 1 and rev = 12. Dropping that middle digit with rev // 10 handles the case.

Reversing the entire number

✗ Wrong
while x > 0:
    rev = rev * 10 + x % 10
    x //= 10
✓ Right
while x > rev:

A full reversal of a value near the 32-bit maximum overflows in C++/Java before the comparison happens. Stopping at the midpoint keeps both halves small enough to be safe.

06

Edge cases

Negative number, e.g. -121

Return False immediately — the minus sign has no counterpart at the back.

Number ending in 0 but not 0, e.g. 10

Return False immediately — the reversal would need a leading zero.

Zero

Passes the guard (x == 0 is excluded from the trailing-zero rule) and the loop never runs, so 0 == 0 returns True.

Odd digit count, e.g. 12321

rev ends up holding the middle digit; comparing against rev // 10 discards it, since a lone middle digit always mirrors itself.

07

Complexity

Time
O(log n)
Space
O(1)
We touch roughly half the digits of x, and a number has about log10(n) digits — no string and no extra buffer.