5 Best Ways to Check if a Number is a Palindrome Without Using Strings in Python

πŸ’‘ Problem Formulation: Determining whether a number is a palindrome involves checking if the number reads the same backward as forward without converting it into a string. For instance, the number 121 is a palindrome since it remains 121 when reversed, but 123 is not since it becomes 321 when reversed. This article explores five different methods to solve this problem using Python.

Method 1: Reversed Integer Comparison

The first method involves reversing the number by reconstructing it backwards and then comparing the original number with the reversed one. This is achieved by iteratively extracting the last digit of the number, appending it to the reversed number, and then truncating the original number by one digit from the end.

Here’s an example:

def is_palindrome(num):
    original, reversed_num = num, 0
    while num > 0:
        reversed_num = (reversed_num * 10) + (num % 10)
        num //= 10
    return original == reversed_num

print(is_palindrome(121)) # Output: True
print(is_palindrome(123)) # Output: False

The above code snippet takes a number and reverses it by extracting each digit and appending it to a new number. The final comparison checks if the reversed number is equal to the initial number, hence determining if it’s a palindrome.

Method 2: Recursion Using Partial Number

Recursion can also be utilized by recursively stripping away digits and comparing the partially reversed number with the remaining original number. This method works by pairing digits from opposite ends moving towards the center.

Here’s an example:

def is_palindrome_recursive(num, copy=None):
    if copy is None:
        copy = num
    if num == 0:
        return copy == 0
    remainder, recursive_check = divmod(copy, 10)
    return (num == recursive_check) or is_palindrome_recursive(num // 10, remainder)

print(is_palindrome_recursive(121)) # Output: True
print(is_palindrome_recursive(123)) # Output: False

The code uses a recursive function to compare the partially reversed number with the remaining number until the base case is met. It’s an elegant solution but can be less intuitive to understand.

Method 3: Mathematical Palindrome Verification

This approach differs by not reconstructing the number. Instead, it calculates the number of digits and verifies palindrome traits mathematically, comparing mirrored digits by their position.

Here’s an example:

def is_palindrome_math(num):
    if num = 10:
        div *= 10
    while num:
        left = num // div
        right = num % 10
        if left != right:
            return False
        num = (num % div) // 10
        div /= 100
    return True

print(is_palindrome_math(121)) # Output: True
print(is_palindrome_math(123)) # Output: False

This method checks if the leftmost and rightmost digits are the same, then moves one place inward from both ends of the number and repeats the check. It is efficient but can be more complex to understand.

Method 4: Iterative Middle-Out Comparison

The iterative middle-out comparison takes a different approach by starting from the middle of the number and comparing outwards. It is a less common but equally valid approach to checking for a palindrome.

Here’s an example:

def is_palindrome_middle_out(num):
    num_digits = len(str(num))
    mid = num_digits // 2
    left, right = divmod(num, 10**mid)
    right = right // 10 if num_digits % 2 else right
    while left and right:
        if left % 10 != right % 10:
            return False
        left //= 10
        right //= 10
    return True

print(is_palindrome_middle_out(121)) # Output: True
print(is_palindrome_middle_out(123)) # Output: False

This unconventional approach converts the number to a string only for calculating its length which is necessary for finding the middle digit. It then peels off digits from both sides for comparison.

Bonus Method 5: One-Liner Using Reduce

The one-liner method uses Python’s functools module and the reduce function to compare each digit without the explicit need for loops or recursive calls, showcasing Python’s functional programming abilities.

Here’s an example:

from functools import reduce

is_palindrome_one_liner = lambda num: num == reduce(lambda x, y: x * 10 + y, [int(digit) for digit in str(num)])

print(is_palindrome_one_liner(121)) # Output: True
print(is_palindrome_one_liner(123)) # Output: False

This one-liner packs a punch by using the reduce function to build the reversed number and immediately compare it with the original number, resulting in a terse yet effective palindrome check.

Summary/Discussion

  • Method 1: Reversed Integer Comparison. Direct and intuitive. Easy to implement. Can be limited by integer overflow in other programming languages.
  • Method 2: Recursion Using Partial Number. Elegant and less code complexity. Not as efficient as iterative solutions due to function call overheads. May cause stack overflow for very large numbers.
  • Method 3: Mathematical Palindrome Verification. Mathematically robust and does not reverse the number. Complexity in understanding the approach. Can be more efficient for very large numbers.
  • Method 4: Iterative Middle-Out Comparison. Unconventional and insightful. Relies on length calculation. Might present a clearer approach for numbers with an even number of digits.
  • Method 5: One-Liner Using Reduce. Compact and functional. Relies on converting number into string for iteration, which bends the rules of the original problem statement.