Reverse Integer
Platform: LeetCode
Difficulty Level: Medium
Link: reverse integer
Problem
Input
x: 32-bit signed integer
Constraints
- INT32_MIN <= x <= INT32_MAX
Goal
- Reverse the digits of the integer
x. x_reverseshould be in the signed 32-bit range[-2^31, 2^31 - 1].- Return
0ifx_reverseis not in the range.
Assumptions
- The environment does not allow us to store signed or unsigned 64-bit integers.
Examples
Example 1:
Input: x = 123
Output: 321
Example 2:
Input: x = -123
Output: -321
Example 3:
Input: x = 120
Output: 21
Solutions
Approach 1: String Conversion
The most naive or the bruteforce approach is string conversion.
- Get the absolute integer of
x(remove the negative sign bit) - Convert absolute integer to string
- Reverse the string
- Convert the reversed string back to integer
- If
xwas negative, attach the negative sign bit to the reversed integer - Check if the reversed integer is in signed 32-bit range
Code
class Solution:
def reverse(self, x: int) -> int:
INT32_MIN = -2**31
INT32_MAX = 2**31 - 1
sign = -1 if x < 0 else 1
x_abs = abs(x)
x_str = str(x_abs)
x_str_rev = x_str[::-1]
x_int_rev = int(x_str_rev)
x_int_rev = x_int_rev * sign
if INT32_MIN <= x_int_rev <= INT32_MAX:
return x_int_rev
return 0Complexity Analysis
Let n be the number,
Time
- int to string conversion =
- reverse string =
- string to int conversion =
Time =
Space
- string representation =
- reversed string =
Space =
Comments
- The assumption is the environment does not allow us to store 64-bit signed or unsigned integers. But in this approach, we are first building the reversed integer and then checking whether it is in 32-bit range. Though the solution is accepted by LeetCode, but it violates the assumption.
- Since we are converting the integer to string, it introduces additional space complexity.
Approach 2: modulo and division
The efficient math way to reverse the integer is to strip the digits one by one using modulo and division approach.
For example, consider x = 123.
We want to build x_reverse i.e. 321.
Extracting the last digit
We can get the digit at ones place using modulo operation. Modulo will give the remainder of the division.x % 10 123 % 10 = 3Strip off the last digit from x
Remove the last digit from x using floor division.x = x // 10 x = 123 // 10 = 12Repeat the above steps
12 % 10 = 2 12 // 10 = 1 1 % 10 = 1 1 // 10 = 0Building the reversed number, digit by digit
x_reverse = 0 x_reverse = x_reverse * 10 + 3 = 3 x_reverse = x_reverse * 10 + 2 = 30 + 2 = 32 x_reverse = x_reverse * 10 + 1 = 320 + 1 = 321
So for each digit we perform below 3 operations:
digit = x % 10
x = x // 10
x_reverse = x_reverse * 10 + digitAdditionally, we also want to make sure that we don’t exceed the signed or unsigned 32-bit range. We want to check this condition before constructing the number to avoid overflow error.
For every digit that we append to the x_reverse, before appending we want to ensure that it will not exceed the specified signed or unsigned 32-bit range. In simple words, the below condition should be satisfied.
INT32_MIN <= x_reverse * 10 + digit <= INT32_MAX
-2147483648 <= x_reverse * 10 + digit <= 2147483647The challenge is we need to check this condition without computing the number. We need to look at the above condition from a different perspective.
Lets Consider some examples:
x inside the range
x = 34865 x_reverse = 56843 INT32_MIN <= x_reverse <= INT32_MAX ----> truex at the positive boundary
x = INT32_MAX = 2147483647 x_reverse = 7463847412 INT32_MIN <= x_reverse <= INT32_MAX ----> falseWhen the input is the largest 32-bit positive number, we clearly see that the reverse of it overflows.
x at the negative boundary
x = INT32_MIN = -2147483648 x_reverse = -8463847412 INT32_MIN <= x_reverse <= INT32_MAX ----> falseWhen the input is the smallest 32-bit negative number, we clearly see that the reverse of it overflows.
Since we want to check the range before appending the next digit at ones place, we strip one digit at ones place from the INT32_MAX and INT32_MIN.
INT32_MIN <= x_reverse * 10 + digit <= INT32_MAX
INT32_MIN - digit <= x_reverse * 10 <= INT32_MAX - digit
(INT32_MIN - digit) / 10 <= x_reverse <= (INT32_MAX - digit) / 10
Irrespective of what the digit is, since we are dividing by 10, it is exactly same as floor division which will strip off the last digit
INT32_MIN // 10 = -214748364
INT32_MAX // 10 = 214748364
-214748364 <= x_reverse <= 214748364Hence, before appending the new digit, this should be our limit to avoid overflow.
Lets consider some examples:
x is inside the boundary
x = 34865 x_reverse = 0 1. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 5 x = 3486 x_reverse = 5 2. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 6 x = 348 x_reverse = 56 3. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 8 x = 34 x_reverse = 568 4. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = 3 x_reverse = 5684 5. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 3 x = 0 x_reverse = 56843Here before appending each digit we are checking whether the current x_reverse is inside the derived range.
x is at the positive boundary
x = 2147483647 x_reverse = 0 1. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 7 x = 214748364 x_reverse = 7 2. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = 21474836 x_reverse = 74 3. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 6 x = 2147483 x_reverse = 746 4. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 3 x = 214748 x_reverse = 7463 5. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 8 x = 21474 x_reverse = 74638 6. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = 2147 x_reverse = 746384 7. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 7 x = 214 x_reverse = 7463847 8. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = 21 x_reverse = 74638474 9. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 1 x = 2 x_reverse = 746384741 10. -214748364 <= x_reverse <= 214748364 ? ---> falseHere, we see that as we append the digits to x_reverse, when the number of digits in x_reverse is equal to the number of digits in INT32_MAX // 10 and INT32_MIN // 10, we get to know that x_reverse will overflow if we append one more digit. This logic helps us check if we can append more digits or not. Since we want to ensure that we don’t overflow, we want to stop one digit before and hence we strip off one digit in INT32_MIN and INT32_MAX.
x is at the negative boundary
x = -2147483648 x_reverse = 0 1. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 8 x = -214748364 x_reverse = -8 2. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = -21474836 x_reverse = -84 3. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 6 x = -2147483 x_reverse = -846 4. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 3 x = -214748 x_reverse = -8463 5. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 8 x = -21474 x_reverse = -84638 6. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = -2147 x_reverse = -846384 7. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 7 x = -214 x_reverse = -8463847 8. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 4 x = -21 x_reverse = -84638474 9. -214748364 <= x_reverse <= 214748364 ? ---> true digit = 1 x = -2 x_reverse = -846384741 10. -214748364 <= x_reverse <= 214748364 ? ---> false
Given the constraint INT32_MIN <= x <= INT32_MAX, we saw above that for x at the negative and positive boundaries, reverse of x overflows.
Till now our condition to check for overflow is INT32_MIN // 10 <= x_reverse <= INT32_MAX // 10.
But if we carefully evaluate the equality condition:
When x_reverse == INT32_MIN // 10 = -214748364
For the above x_reverse, value of input x will be
x = -463847412_
Where the last digit can be 0-9.
Irrespective of the last digit, -463847412_ is not in the 32-bit range which violates the constraint INT32_MIN <= x <= INT32_MAX.
Hence, x_reverse cannot be equal to INT32_MIN // 10.
Similarly,
When x_reverse == INT32_MAX // 10 = 214748364
For the above x_reverse, value of input x will be
x = 463847412_
Where the last digit can be 0-9.
Irrespective of the last digit, 463847412_ is not in the 32-bit range which again violates the constraint INT32_MIN <= x <= INT32_MAX.
Hence, x_reverse cannot be equal to INT32_MAX // 10.Hence our final check for overflow is
INT32_MIN // 10 < x_reverse < INT32_MAX // 10Code
class Solution:
def reverse(self, x: int) -> int:
INT32_MIN = -2**31
INT32_MAX = 2**31 - 1
sign = -1 if x < 0 else 1
x = abs(x)
x_reverse = 0
while x != 0:
# check for overflow before appending the digit
if x_reverse > INT32_MAX // 10:
return 0
digit = x % 10
x = x // 10
x_reverse = x_reverse * 10 + digit
return x_reverse * signIf we look at the solution in python, we are using abs(x).
We are handling the sign of the number seperately. Why so?
Division in python behaves different as compared to other languages like C/C++/Go. (Check the implementation in Go).
dharmin@workstation:~$ python3
Python 3.12.3 (main, Mar 23 2026, 19:04:32) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 7 / 3
2.3333333333333335
>>> 7 // 3
2
>>> -7 / 3
-2.3333333333333335
>>> -7 // 3
-3
>>> 7 % 3
1
>>> -7 % 3
2
>>>In python,
- Modulo returns the remainder with the same sign as divisor.
- Floor division divides the numbers and rounds down the quotient to the nearest integer.
Python does this to satisfy the math:
dividend = divisor * quotient + remainderWith positive numbers,
7 // 3 = 2
7 % 3 = 1
7 = 3 * 2 + 1With negative numbers,
-7 // 3 = -3
-7 % 3 = 2
-7 = 3 * -3 + 2Hence, to not deal with this behaviour, we are using abs(x).
Since our overflow condition is -214748364 < x_reverse < 214748364, the upper bound and lower bound are symmetrical.
Hence if x_reverse is not in the range, then -x_reverse will also not be in the range.
Complexity Analysis
Let n be the number,
Time
- traversing each digit once in number =
Time =
Space
- no extra space used
Space =
Comments
- The assumption that the environment does not allow us to store signed or unsigned 64-bit numbers is now satisfied. We are checking if the number is in signed or unsigned 32-bit range before computing the number to prevent overflow error.
- Compared to the string conversion approach, this approach is efficient in terms of space.