Problem
Given a signed 32-bit integer, return the same number with its digits in reverse order. If the reversed value cannot be represented as a 32-bit signed integer (outside the range [-2ยณยน, 2ยณยน โ 1]), return 0 instead. Note that the environment doesn't allow 64-bit integers.
- Input:
x = 123 - Output:
321 - Explanation: The digits reversed are 3, 2, 1, which form 321.
Additional examples:
- Input:
x = -123โ Output:-321 - Input:
x = 120โ Output:21(leading zero dropped) - Input:
x = 1534236469โ Output:0(reversed value 9646324351 overflows 32 bits)
Intuition
Peel one digit at a time from the right of the input using modulo, and stack it onto the left of the result. The tricky constraint is 32-bit overflow: by the time the result overflows, it's too late to detect it. So the check must happen before the multiply โ if result is already large enough that multiplying by 10 would exceed INT_MAX, return 0 immediately.
Solution โ Digit Extraction
Extract the rightmost digit with % 10, shrink the input with integer division, and check for overflow before each result = result * 10 + digit step.
One language quirk: Python's // is floor division, so -123 // 10 = -13 (not -12), meaning modulo also behaves differently from C/Java for negative numbers. The cleanest fix is to strip the sign at the start, work with the absolute value, and restore the sign at the end. Java and C++ truncate toward zero natively, so they handle negative inputs without special treatment.
- Record the sign and work with the absolute value (Python only; Java/C++ skip this).
- Loop while
x != 0: extractdigit = x % 10, then shrinkxwith integer division. - Before updating result, check: if
result > INT_MAX // 10, multiplying by 10 will overflow โ return 0. Ifresult == INT_MAX // 10anddigit > 7, adding the digit tips it over โ return 0. - Set
result = result * 10 + digit. - Return
resultwith the original sign applied.
1def reverse(x: int) -> int:
2 INT_MAX = 2**31 - 1 # 2147483647; ends in digit 7
3 sign = 1 if x >= 0 else -1
4 x = abs(x) # avoid Python floor-division quirk on negatives
5 result = 0
6 while x != 0:
7 digit = x % 10
8 x //= 10
9 # multiply-then-add would exceed INT_MAX, so bail out now
10 if result > INT_MAX // 10 or (result == INT_MAX // 10 and digit > 7):
11 return 0
12 result = result * 10 + digit
13 return sign * resultTime: O(log x) โ one iteration per decimal digit.
Space: O(1) โ only a handful of integer variables.
Complexity Summary
| Approach | Time | Space | When to use |
|---|---|---|---|
| Digit Extraction | O(log x) | O(1) | Always โ there is no meaningfully different alternative |
Common Mistakes
- Checking overflow after the multiply. By the time
result * 10executes, it has already wrapped around in Java/C++ or become a giant Python int. The guard must come before the multiply. - Using Python's
//on negative numbers without adjusting.-123 // 10is-13in Python (floor), not-12(truncate). This shifts the digit extraction incorrectly. Stripping the sign and working withabs(x)sidesteps this entirely. - Off-by-one on the boundary digit. When
result == INT_MAX // 10 = 214748364, only digits> 7overflow (INT_MAX ends in 7). Using>= 7would incorrectly reject inputs that produce a valid 2147483647. - Forgetting the negative boundary. INT_MIN = -2147483648 ends in digit 8, so the guard for the minimum is
digit < -8, notdigit < -7. This edge case only fires if the reversed number would equal exactly INT_MIN. - Assuming
x = 0needs special handling. It doesn't โ the loop simply doesn't execute andresult = 0is returned correctly.
Related Problems
palindrome-numberโ also uses digit-by-digit extraction to inspect a number without converting it to a stringhappy-numberโ repeatedly extracts digits (squares of each) to detect a cycleadd-binaryโ digit-by-digit construction of a result with carrymultiply-stringsโ digit-by-digit arithmetic where native types cannot hold the valuepowx-nโ mathematical edge cases including negative exponents and overflow-adjacent boundaries