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 [-2^31, 2^31 - 1]
, then return 0
. Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
Here are a few examples:
Input: x = 123
Output: 321
Input: x = -123
Output: -321
Input: x = 120
Output: 21
Could you provide an algorithm to solve this problem efficiently? Consider the constraints and edge cases such as overflow, negative numbers, and trailing zeros. Explain the time and space complexity of your solution.
A naive approach would be to convert the integer to a string, reverse the string, and then convert the string back to an integer. However, we must handle the negative sign and the overflow/underflow cases.
def reverse_integer_naive(x):
s = str(x)
sign = -1 if s[0] == '-' else 1
if sign == -1:
s = s[1:]
reversed_s = s[::-1]
result = sign * int(reversed_s)
if result < -2**31 or result > 2**31 - 1:
return 0
return result
The optimal solution avoids using strings and performs the reversal using mathematical operations. We can extract the last digit using the modulo operator (%
) and build the reversed number incrementally. We also need to check for overflow and underflow before updating the reversed number.
def reverse_integer_optimal(x):
reversed_x = 0
sign = 1 if x >= 0 else -1
x = abs(x)
while x > 0:
pop = x % 10
x //= 10
# Check for overflow before multiplying
if reversed_x > 2**31 // 10 or (reversed_x == 2**31 // 10 and pop > 7):
return 0
# Check for underflow before multiplying
if reversed_x < (-2)**31 // 10 or (reversed_x == (-2)**31 // 10 and pop < -8):
return 0
reversed_x = reversed_x * 10 + pop
return sign * reversed_x