7. Reverse Integer
Problem Description
You need to reverse the digits of a given 32-bit signed integer x
.
For example:
- If
x = 123
, return321
- If
x = -123
, return-321
- If
x = 120
, return21
The key constraint is that the reversed integer must stay within the valid range for a 32-bit signed integer, which is [-2^31, 2^31 - 1]
or [-2147483648, 2147483647]
. If reversing the digits would cause the number to overflow (exceed this range), you should return 0
instead.
An important restriction is that you cannot use 64-bit integers to check for overflow - you must work within the constraints of 32-bit arithmetic. This means you need to detect potential overflow before it happens, rather than reversing first and then checking if the result is out of bounds.
The challenge lies in:
- Extracting digits from the original number one by one
- Building the reversed number by appending these digits
- Checking for overflow before each digit is added to prevent going outside the 32-bit range
- Handling both positive and negative numbers correctly
Intuition
To reverse an integer, we need to extract its digits from right to left and build a new number from left to right. The natural approach is to repeatedly take the last digit using the modulo operator (x % 10
) and add it to our result.
The main challenge is detecting overflow without using 64-bit integers. We need to check if adding another digit would cause overflow before we actually add it.
Let's think about when overflow happens. If we have a partial result ans
and want to add another digit y
, the new value would be ans * 10 + y
. This needs to stay within [-2^31, 2^31 - 1]
.
For positive numbers, we need: ans * 10 + y ≤ 2^31 - 1
Rearranging: ans ≤ (2^31 - 1 - y) / 10
Since y
is at most 9, we can simplify our check to: ans ≤ (2^31 - 1) / 10
Similarly for negative numbers: ans ≥ -2^31 / 10
So before multiplying ans
by 10 and adding the next digit, we check if ans
is within the safe range [-2^31 / 10, (2^31 - 1) / 10]
. If it's outside this range, multiplying by 10 would definitely cause overflow.
There's a subtle issue with negative numbers in Python: when we do x % 10
on a negative number, Python returns a positive remainder. For example, -123 % 10 = 7
(not -3
). To handle this, when x
is negative but the remainder is positive, we adjust by subtracting 10 to get the correct negative digit.
The algorithm repeatedly:
- Checks if we can safely add another digit without overflow
- Extracts the last digit (with adjustment for negatives)
- Appends it to our result
- Removes the last digit from the original number
This way, we build the reversed number digit by digit while ensuring we never overflow.
Learn more about Math patterns.
Solution Approach
We implement the solution using a mathematical approach that extracts digits one by one and builds the reversed number while checking for overflow.
First, we initialize our variables:
ans = 0
: stores the reversed numbermi = -2^31
andmx = 2^31 - 1
: the boundaries of 32-bit signed integer range
The main algorithm uses a while loop that continues as long as x
is not zero:
-
Overflow Check: Before adding a new digit, we check if
ans
is within the safe range[mi // 10 + 1, mx // 10]
. Ifans < mi // 10 + 1
orans > mx // 10
, multiplying by 10 would cause overflow, so we return 0.The mathematical reasoning: For
ans * 10 + y
to not overflow:- Upper bound:
ans * 10 + y ≤ mx
impliesans ≤ mx // 10
(sincey ≤ 9
) - Lower bound:
ans * 10 + y ≥ mi
impliesans ≥ mi // 10 + 1
(accounting for negative remainder)
- Upper bound:
-
Extract Last Digit: We get the last digit using
y = x % 10
. However, Python's modulo operation with negative numbers needs special handling. Whenx < 0
buty > 0
, we adjust by subtracting 10 fromy
to get the correct negative digit.Example:
-123 % 10 = 7
in Python, but we want-3
, so we do7 - 10 = -3
. -
Build Reversed Number: We append the digit to our result:
ans = ans * 10 + y
. -
Remove Last Digit: We remove the processed digit from
x
usingx = (x - y) // 10
. We subtracty
first to ensure correct integer division for both positive and negative numbers.
The loop continues until all digits are processed (x
becomes 0), and we return the reversed number ans
.
The time complexity is O(log(x))
since we process each digit once, and the space complexity is O(1)
as we only use a constant amount of extra space.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through reversing x = -123
step by step.
Initial Setup:
x = -123
ans = 0
mi = -2147483648
(-2^31)mx = 2147483647
(2^31 - 1)
Iteration 1:
- Check overflow: Is
ans
in range[mi // 10 + 1, mx // 10]
?ans = 0
is in range[-214748364, 214748364]
✓
- Extract digit:
y = -123 % 10 = 7
(Python's modulo behavior) - Adjust for negative: Since
x < 0
andy > 0
, adjust:y = 7 - 10 = -3
- Build result:
ans = 0 * 10 + (-3) = -3
- Remove digit:
x = (-123 - (-3)) // 10 = -120 // 10 = -12
Iteration 2:
- Check overflow: Is
ans = -3
in range[-214748364, 214748364]
? ✓ - Extract digit:
y = -12 % 10 = 8
- Adjust for negative: Since
x < 0
andy > 0
, adjust:y = 8 - 10 = -2
- Build result:
ans = -3 * 10 + (-2) = -30 + (-2) = -32
- Remove digit:
x = (-12 - (-2)) // 10 = -10 // 10 = -1
Iteration 3:
- Check overflow: Is
ans = -32
in range[-214748364, 214748364]
? ✓ - Extract digit:
y = -1 % 10 = 9
- Adjust for negative: Since
x < 0
andy > 0
, adjust:y = 9 - 10 = -1
- Build result:
ans = -32 * 10 + (-1) = -320 + (-1) = -321
- Remove digit:
x = (-1 - (-1)) // 10 = 0 // 10 = 0
Result: The loop ends since x = 0
. Return ans = -321
.
For a positive example like x = 120
:
- First iteration: Extract 0,
ans = 0
,x = 12
- Second iteration: Extract 2,
ans = 0 * 10 + 2 = 2
,x = 1
- Third iteration: Extract 1,
ans = 2 * 10 + 1 = 21
,x = 0
- Result:
21
The overflow check prevents issues. For example, if we try to reverse 1534236469
:
- After several iterations, we'd have
ans = 964632435
andx = 1
- Before adding the last digit, we check: Is
964632435
in range[-214748364, 214748364]
? - No!
964632435 > 214748364
, so multiplying by 10 would overflow - Return
0
immediately
Solution Implementation
1class Solution:
2 def reverse(self, x: int) -> int:
3 """
4 Reverses the digits of a 32-bit signed integer.
5 Returns 0 if the reversed integer overflows.
6
7 Args:
8 x: A 32-bit signed integer
9
10 Returns:
11 The reversed integer, or 0 if overflow occurs
12 """
13 result = 0
14
15 # Define 32-bit integer boundaries
16 MIN_INT = -(2**31) # -2147483648
17 MAX_INT = 2**31 - 1 # 2147483647
18
19 while x != 0:
20 # Check for potential overflow before multiplying by 10
21 # If result * 10 would exceed boundaries, return 0
22 if result < MIN_INT // 10 + 1 or result > MAX_INT // 10:
23 return 0
24
25 # Extract the last digit
26 digit = x % 10
27
28 # Handle negative numbers: Python's modulo returns positive remainder
29 # For negative x, we need to adjust the digit to be negative
30 if x < 0 and digit > 0:
31 digit -= 10
32
33 # Build the reversed number
34 result = result * 10 + digit
35
36 # Remove the last digit from x
37 # Using (x - digit) ensures proper division for negative numbers
38 x = (x - digit) // 10
39
40 return result
41
1class Solution {
2 /**
3 * Reverses the digits of a 32-bit signed integer.
4 * Returns 0 if the reversed integer would overflow.
5 *
6 * @param x the integer to reverse
7 * @return the reversed integer, or 0 if overflow would occur
8 */
9 public int reverse(int x) {
10 int reversedNumber = 0;
11
12 // Process each digit from right to left
13 while (x != 0) {
14 // Check for potential overflow before multiplying by 10
15 // Integer.MAX_VALUE = 2147483647, Integer.MIN_VALUE = -2147483648
16 if (reversedNumber > Integer.MAX_VALUE / 10 || reversedNumber < Integer.MIN_VALUE / 10) {
17 return 0;
18 }
19
20 // Extract the last digit and add it to the reversed number
21 int lastDigit = x % 10;
22 reversedNumber = reversedNumber * 10 + lastDigit;
23
24 // Remove the last digit from x
25 x = x / 10;
26 }
27
28 return reversedNumber;
29 }
30}
31
1class Solution {
2public:
3 int reverse(int x) {
4 int reversedNumber = 0;
5
6 // Process each digit of the input number
7 while (x != 0) {
8 // Check for potential overflow before multiplying by 10
9 // INT_MAX = 2147483647, INT_MIN = -2147483648
10 // If reversedNumber > INT_MAX/10, then reversedNumber * 10 will overflow
11 // If reversedNumber < INT_MIN/10, then reversedNumber * 10 will underflow
12 if (reversedNumber > INT_MAX / 10 || reversedNumber < INT_MIN / 10) {
13 return 0;
14 }
15
16 // Extract the last digit and append it to the reversed number
17 int lastDigit = x % 10;
18 reversedNumber = reversedNumber * 10 + lastDigit;
19
20 // Remove the last digit from the original number
21 x /= 10;
22 }
23
24 return reversedNumber;
25 }
26};
27
1/**
2 * Reverses the digits of a 32-bit signed integer
3 * @param x - The integer to reverse
4 * @returns The reversed integer, or 0 if the result would overflow
5 */
6function reverse(x: number): number {
7 // Define 32-bit signed integer boundaries
8 const MIN_INT32: number = -(2 ** 31);
9 const MAX_INT32: number = 2 ** 31 - 1;
10
11 let result: number = 0;
12
13 // Process each digit from right to left
14 while (x !== 0) {
15 // Check for potential overflow before multiplying by 10
16 // Using bitwise OR with 0 (~~) to truncate towards zero
17 if (result < ~~(MIN_INT32 / 10) || result > ~~(MAX_INT32 / 10)) {
18 return 0;
19 }
20
21 // Append the last digit of x to result
22 result = result * 10 + (x % 10);
23
24 // Remove the last digit from x (truncate towards zero)
25 x = ~~(x / 10);
26 }
27
28 return result;
29}
30
Time and Space Complexity
The time complexity is O(log |x|)
, where |x|
is the absolute value of x
. This is because the while loop iterates through each digit of the input number x
. The number of digits in x
is proportional to log₁₀(|x|)
, which can be expressed as O(log |x|)
. In each iteration, the algorithm performs constant-time operations: modulo operation, division, multiplication, and addition.
The space complexity is O(1)
. The algorithm only uses a fixed amount of extra space regardless of the input size. The variables ans
, mi
, mx
, and y
are the only additional variables created, and they don't scale with the input size. No additional data structures like arrays or recursive call stacks are used.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Overflow Detection Timing
Pitfall: Many developers check for overflow after performing the multiplication result * 10 + digit
, but this defeats the purpose since the overflow has already occurred.
# WRONG: Checking after the operation result = result * 10 + digit if result > MAX_INT or result < MIN_INT: return 0
Solution: Always check BEFORE the multiplication to predict if overflow will occur:
# CORRECT: Check before the operation if result > MAX_INT // 10 or (result == MAX_INT // 10 and digit > 7): return 0 if result < MIN_INT // 10 or (result == MIN_INT // 10 and digit < -8): return 0 result = result * 10 + digit
2. Mishandling Python's Modulo with Negative Numbers
Pitfall: Python's modulo operator behaves differently than C++ or Java. For negative numbers, x % 10
returns a positive value, which can lead to incorrect results.
# Example: -123 % 10 = 7 (not -3 as you might expect) # WRONG: Using modulo directly without adjustment digit = x % 10 result = result * 10 + digit # This will give wrong sign
Solution: Adjust the digit when dealing with negative numbers:
# CORRECT: Adjust for negative numbers digit = x % 10 if x < 0 and digit > 0: digit -= 10
3. Using Simple Integer Division for Negative Numbers
Pitfall: Using x // 10
directly for negative numbers can give unexpected results due to floor division rounding toward negative infinity.
# Example: -123 // 10 = -13 (rounds down) # But after extracting digit 7, we have -123 - 7 = -130 # -130 // 10 = -13 (correct)
Solution: Subtract the extracted digit before division to ensure correct behavior:
# CORRECT: Subtract digit before division x = (x - digit) // 10
4. Incorrect Boundary Check Formula
Pitfall: Using MIN_INT // 10
directly without adjustment for the lower bound can miss edge cases.
# WRONG: Simple division check if result < MIN_INT // 10 or result > MAX_INT // 10: return 0
Solution: For the minimum boundary, use MIN_INT // 10 + 1
to account for the fact that the minimum value's absolute value is one greater than the maximum:
# CORRECT: Adjusted boundary check if result < MIN_INT // 10 + 1 or result > MAX_INT // 10: return 0
5. Not Considering the Last Digit in Overflow Check
Pitfall: When result
equals MAX_INT // 10
or MIN_INT // 10
, the last digit determines whether overflow occurs, but this is often overlooked.
Solution: For precise overflow detection at the boundary:
# More precise check (alternative approach) if result > MAX_INT // 10: return 0 if result == MAX_INT // 10 and digit > MAX_INT % 10: return 0 # Similar logic for MIN_INT
Consider the classic dynamic programming of longest increasing subsequence:
Find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order.
For example, the length of LIS for [50, 3, 10, 7, 40, 80]
is 4
and LIS is
[3, 7, 40, 80]
.
What is the recurrence relation?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!