Determining Palindrome Numbers Without Extra Space in Python
Understanding the Problem
The objective is to verify if a given integer is a palindrome. A palindrome reads the same backward as forward. For integers, this means that if we reverse the sequence of digits, the value remains identical. The problem imposes a strict constraint: the solution must not use extra space. This implies that the space complexity should be O(1), meaning the memory usage must remain constant regardless of the input size.
First, we must define the edge cases:
- Single-digit integers (0 through 9) are inherently palindromes.
- Negative integers cannot be palindromes because the negative sign only appears at the beginning, not the end.
- Integers ending in 0 (except 0 itself) cannot be palindromes, as integers do not have leading zeros.
Analyzing the Space Constraint
A common intuitive approach in high-level languages like Python is to convert the integer into a string, reverse the string, and check if it matches the original. While this works, it violates the O(1) space constraint. Converting an integer to a string creates a new object, allocating memory proportional to the number of digits. Since the prompt explicitly forbids "extra space," we must rely on mathematical operations to manipulate the digits directly.
Mathematical Approach: Reversing Half of the Number
Reversing the entire integer mathematical is possible, but it risks integer overflow in languages with fixed-size integer limits. Even in Python, where integers can be arbitrarily large, reversing the full number is unnecessary. We can optimize by reversing only half of the number.
The logic involves comparing the first half of the digits with the reversed second half. If the original number is a palindrome, the reversed second half will be equal to the first half.
- Even number of digits: If the input is
1221, the reversed second half becomes12, and the remaining first half is12. They are equal. - Odd number of digits: If the input is
12321, the reversed second half becomes123, and the first half is12. The middle digit (3) doesn't affect the palindrome property. We can remove it from the reversed half by performing integer division by 10.
We iterate through the number, popping the last digit off the original number and pushing it onto the reversed number. We stop when the original number becomes less than or equal to the reversed number, indicating we have processed half of the digits.
Implementation
Below is the Python implementation incorporating the logic described. We first handle the edge cases for negative numbers and multiples of 10. Then, we enter the loop to reverse half of the digits.
class Solution:
def isPalindrome(self, num: int) -> bool:
# Negative numbers and numbers ending with 0 (except 0) are not palindromes
if num < 0 or (num % 10 == 0 and num != 0):
return False
reversed_half = 0
while num > reversed_half:
# Extract the last digit of num and add it to reversed_half
reversed_half = reversed_half * 10 + num % 10
# Remove the last digit from num
num //= 10
# For even digits: num == reversed_half (e.g., 1221 -> 12 == 12)
# For odd digits: num == reversed_half // 10 (e.g., 12321 -> 12 == 123 // 10)
return num == reversed_half or num == reversed_half // 10
This approach ensures we only use a few variables for storage, adhering to the O(1) space complexity requirement.