Given a signed 32-bit integer x
, return x
with its digits reversed. If reversing x
causes the value to go outside the signed 32-bit integer range [-231, 231 - 1]
, then return 0
.
Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
Example 1:
Input: x = 123 Output: 321
Example 2:
Input: x = -123 Output: -321
Example 3:
Input: x = 120 Output: 21
Constraints:
-231 <= x <= 231 - 1
This problem requires reversing a 32-bit signed integer. The challenge lies in handling potential integer overflow during the reversal process. The optimal solution utilizes a mathematical approach with careful overflow checks.
Approach:
The core idea is to iteratively extract the last digit of the input integer, and then prepend it to the reversed integer. This is done using the modulo operator (%) and integer division (/).
Initialization: We initialize a variable ans
to 0, which will store the reversed integer.
Iteration: The while
loop continues as long as the input integer x
is not zero. Inside the loop:
Overflow Check: Before adding the next digit, we check for potential overflow. The condition ans < Integer.MIN_VALUE / 10 || ans > Integer.MAX_VALUE / 10
(or its equivalent in other languages) ensures that the next multiplication by 10 and addition will not exceed the limits of a 32-bit integer. If overflow is detected, we immediately return 0.
Digit Extraction: We extract the last digit using x % 10
.
Reverse Appending: We append this digit to ans
by multiplying ans
by 10 and adding the extracted digit: ans = ans * 10 + x % 10;
.
Integer Division: We remove the last digit from x
using integer division: x /= 10;
.
Return Value: Once the loop finishes (when x
becomes 0), we return the reversed integer ans
.
Time Complexity: O(log10|x|) - The number of iterations is proportional to the number of digits in the input integer x
. The logarithm base 10 is used because we're dealing with decimal digits.
Space Complexity: O(1) - The algorithm uses a constant amount of extra space regardless of the input size.
Code Examples (with detailed explanations):
The provided code examples in multiple languages all implement this approach. They differ slightly in syntax but follow the same core logic. Let's focus on the Python code for a detailed explanation:
class Solution:
def reverse(self, x: int) -> int:
ans = 0
mi, mx = -(2**31), 2**31 - 1 # Minimum and maximum 32-bit signed integers
while x:
# Overflow Check: Crucial step to prevent exceeding 32-bit limits
if ans < mi // 10 + 1 or ans > mx // 10:
return 0
y = x % 10 # Extract last digit
ans = ans * 10 + y # Append to reversed integer
x //= 10 # Remove last digit from original number
return ans
Explanation of Python Code:
mi
and mx
: These variables store the minimum and maximum values for a 32-bit signed integer.
while x:
: The loop continues until x
becomes 0 (no more digits).
if ans < mi // 10 + 1 or ans > mx // 10:
: This is the crucial overflow check. We're checking if adding the next digit (y
) to ans
will cause an overflow. The slight addition of +1
in the lower bound ensures that negative numbers are treated correctly.
y = x % 10
: This extracts the last digit of x
.
ans = ans * 10 + y
: This appends y
to the reversed integer ans
.
x //= 10
: This performs integer division, effectively removing the last digit from x
.
The other code examples (Java, C++, Go, Rust, JavaScript, C#, PHP) follow the same logic, adapting the syntax and integer limit checks to their respective languages. The overflow check is critical in all of them to prevent unexpected behavior and ensure correct results.