Palindrome Number
Given an integer x, return true if its decimal digits read the same from left to right as from right to left, and false otherwise.
A negative number is never a palindrome, because the minus sign appears only on the left. Numbers are written without leading zeroes, so for example 50 is not a palindrome (it would need to read 05 backwards).
As an extra challenge, solve it without turning the number into a string.
Example 1
Example 2
Example 3
Constraints
-231 <= x <= 231 - 1
Pattern Path · Math, Bits & Strings · problem 34 of 169
x % 10 gives the last digit and x // 10 removes it. Building a reversed number digit by digit is easy from there.Start simple
Convert the number to a string and compare it with its reverse: O(d) time and O(d) extra space for d digits.
The key idea
Peel digits off the right end of x with % 10 and append them to a new number rev with rev * 10 + digit. After k steps, rev holds the last k digits in reverse order, and x holds the remaining leading digits.
A palindrome's second half reversed equals its first half, so you can stop halfway: keep going only while x > rev. At that point either the lengths are equal (even digit count, check x == rev) or rev has one extra digit, the middle one, which does not need a partner (odd digit count, check x == rev // 10).
Two cases must be rejected up front. Negative numbers fail immediately. A number ending in 0 (other than 0 itself) cannot be a palindrome because it would need to start with 0; without this check the half-reversal would wrongly accept values like 10.
Reversing only half also guarantees rev never overflows a 32-bit integer.
Complexity
- Time:
O(log x) - Space:
O(1)
Python
class Solution:
def isPalindrome(self, x):
# Negatives, and numbers ending in 0 (except 0 itself), cannot be palindromes.
if x < 0 or (x % 10 == 0 and x != 0):
return False
rev = 0
while x > rev: # reverse only the second half of the digits
rev = rev * 10 + x % 10
x //= 10
# Even digit count: halves match. Odd: drop the middle digit from rev.
return x == rev or x == rev // 10
JavaScript
var isPalindrome = function(x) {
// Negatives, and numbers ending in 0 (except 0 itself), cannot be palindromes.
if (x < 0 || (x % 10 === 0 && x !== 0)) return false;
let rev = 0;
while (x > rev) { // reverse only the second half of the digits
rev = rev * 10 + (x % 10);
x = Math.floor(x / 10);
}
// Even digit count: halves match. Odd: drop the middle digit from rev.
return x === rev || x === Math.floor(rev / 10);
};
What the interviewer is checking
It checks digit manipulation with % and integer division, careful handling of edge cases like trailing zeroes and negatives, and awareness of overflow when reversing.
Mistakes to avoid
- Forgetting that negative numbers are never palindromes.
- Accepting numbers ending in 0, like 10 or 120, with the half-reversal trick.
- Reversing the full number, which can overflow a 32-bit int in Java or C++.
- Using
/in JavaScript or Python 3 without flooring, which produces fractions.
Follow-ups to expect
- How would you check a palindrome in another base? (Use that base for % and division.)
- Can you find the next palindrome greater than x? (Mirror the left half, then adjust.)
- What about checking a very large number stored as a string? (Two pointers from both ends.)
In real software
Digit-by-digit arithmetic like this appears in checksum algorithms such as the Luhn check on card numbers, and in parsing or formatting numbers without string allocation.