7. Reverse Integer
On LeetCode ->Reformulated question¶
Reverse the decimal digits of a signed 32-bit integer and keep the sign; return 0 if the reversed value is outside [-2^31, 2^31 - 1].
Example:
Key trick¶
Detect overflow while building the reversed number digit by digit.
- Pop the last digit with
% 10and// 10. - Before doing
rev = rev * 10 + digit, check whether that would exceed 32-bit bounds.
Trap¶
- Forgetting the overflow check.
- Using string reversal and only checking overflow at the end, which ignores the "no 64-bit storage" constraint.
- Mishandling negatives because Python
%and//behave differently for negative numbers.
Why this question is interesting?¶
It tests careful integer manipulation.
- You must handle sign, trailing zeros, and overflow cleanly.
- The intended solution is language-aware and avoids "easy but not portable" shortcuts.
Solve the problem with idiomatic python¶
class Solution:
def reverse(self, x: int) -> int:
INT_MAX = 2**31 - 1
sign = -1 if x < 0 else 1
x = abs(x)
rev = 0
while x:
# Extract the last digit and shrink x.
digit = x % 10
x //= 10
# If rev * 10 + digit would overflow 32-bit signed range, stop.
if rev > (INT_MAX - digit) // 10:
return 0
rev = rev * 10 + digit
return sign * rev
- Time: \(O(d)\)
- Space: \(O(1)\)
Pytest test¶
import pytest
@pytest.mark.parametrize(
("x", "expected"),
[
(123, 321),
(-123, -321),
(120, 21),
(0, 0),
(10, 1),
(-10, -1),
(1534236469, 0),
(-1563847412, 0),
(1463847412, 2147483641),
(-2147483412, -2143847412),
],
)
def test_reverse_integer(x, expected):
assert Solution().reverse(x) == expected
Comment my solution¶
Your solution is correct for the shown examples, but it misses the required overflow handling.
1534236469should return0, but your code returns9646324351.- It uses string conversion, which is fine in Python practice, but not the intended interview trick here.
lstrip("0") or "0"is neat and correctly handles inputs like0and120.
class Solution:
def reverse(self, x: int) -> int:
sign = -1 if x < 0 else 1
x_str_reversed = "".join(reversed(str(abs(x)))).lstrip("0") or "0"
return sign * int(x_str_reversed)
# "00012300".lstrip("0") # '12300'
# "000".lstrip("0") # ''
# "000".lstrip("0") or "0" # "0"
## Test
import pytest
@pytest.mark.parametrize(
("x", "expected"),
[(123, 321), (-123, -321), (120, 21)]
)
def test_reverse_integer(x, expected):
assert Solution().reverse(x) == expected
Code¶
import pytest
class Solution:
def reverse(self, x: int) -> int:
INT_MAX = 2**31 - 1
sign = -1 if x < 0 else 1
x = abs(x)
rev = 0
while x:
# Extract the last digit and shrink x.
digit = x % 10
x //= 10
# If rev * 10 + digit would overflow 32-bit signed range, stop.
if rev > (INT_MAX - digit) // 10:
return 0
rev = rev * 10 + digit
return sign * rev
class SolutionStr:
def reverse(self, x: int) -> int:
# Compact Python solution; acceptable in practice, but less faithful
# to the intended "no 64-bit storage" interview constraint.
sign = -1 if x < 0 else 1
rev = int(str(abs(x))[::-1])
rev *= sign
return rev if -(2**31) <= rev <= 2**31 - 1 else 0
@pytest.mark.parametrize(
("x", "expected"),
[
(123, 321),
(-123, -321),
(120, 21),
(0, 0),
(10, 1),
(-10, -1),
(1534236469, 0),
(-1563847412, 0),
(1463847412, 2147483641),
(-2147483412, -2143847412),
],
)
def test_reverse_integer(x, expected):
assert Solution().reverse(x) == expected
## Interactive examples
Solution().reverse(123)
Solution().reverse(-123)
Solution().reverse(120)
Solution().reverse(1534236469)
SolutionStr().reverse(123)