LeetCode 7: Reverse Integer (Math + Overflow Guard)
LeetCode 7MathOverflowToday we solve LeetCode 7 - Reverse Integer.
Source: https://leetcode.com/problems/reverse-integer/
English
Problem Summary
Given a signed 32-bit integer x, return x with digits reversed. If reversing causes overflow outside [-2^31, 2^31-1], return 0. Avoid using a larger integer type to bypass overflow handling.
Key Insight
Process one digit at a time: pop with digit = x % 10, then push into rev = rev * 10 + digit. Before pushing, check whether rev would overflow after multiplying by 10 and adding digit.
Overflow Guard
For 32-bit int range (INT_MAX=2147483647, INT_MIN=-2147483648):
- If rev > INT_MAX/10, overflow on next push.
- If rev == INT_MAX/10 and digit > 7, overflow.
- If rev < INT_MIN/10, underflow.
- If rev == INT_MIN/10 and digit < -8, underflow.
Complexity Analysis
Time: O(log10(|x|)) (one loop per digit).
Space: O(1).
Common Pitfalls
- Reversing first then checking overflow (already too late).
- Losing sign handling for negative numbers.
- Assuming trailing zeros should stay (e.g. 120 -> 21).
- Using string conversion when interview expects arithmetic approach.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int digit = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE / 10 ||
(rev == Integer.MAX_VALUE / 10 && digit > 7)) return 0;
if (rev < Integer.MIN_VALUE / 10 ||
(rev == Integer.MIN_VALUE / 10 && digit < -8)) return 0;
rev = rev * 10 + digit;
}
return rev;
}
}func reverse(x int) int {
rev := 0
for x != 0 {
digit := x % 10
x /= 10
if rev > 214748364 || (rev == 214748364 && digit > 7) {
return 0
}
if rev < -214748364 || (rev == -214748364 && digit < -8) {
return 0
}
rev = rev*10 + digit
}
return rev
}class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x != 0) {
int digit = x % 10;
x /= 10;
if (rev > INT_MAX / 10 || (rev == INT_MAX / 10 && digit > 7)) return 0;
if (rev < INT_MIN / 10 || (rev == INT_MIN / 10 && digit < -8)) return 0;
rev = rev * 10 + digit;
}
return rev;
}
};class Solution:
def reverse(self, x: int) -> int:
INT_MAX = 2**31 - 1
INT_MIN = -2**31
rev = 0
while x != 0:
digit = int(x % 10) if x > 0 else -int((-x) % 10)
x = int(x / 10)
if rev > INT_MAX // 10 or (rev == INT_MAX // 10 and digit > 7):
return 0
if rev < INT_MIN // 10 or (rev == INT_MIN // 10 and digit < -8):
return 0
rev = rev * 10 + digit
return revvar reverse = function(x) {
const INT_MAX = 2147483647;
const INT_MIN = -2147483648;
let rev = 0;
while (x !== 0) {
const digit = x % 10;
x = (x / 10) | 0;
if (rev > 214748364 || (rev === 214748364 && digit > 7)) return 0;
if (rev < -214748364 || (rev === -214748364 && digit < -8)) return 0;
rev = rev * 10 + digit;
}
return rev;
};中文
题目概述
给你一个 32 位有符号整数 x,返回其数字反转后的结果。如果反转后超出区间 [-2^31, 2^31-1],返回 0。
核心思路
每轮弹出一位数字并压入结果:digit = x % 10,rev = rev * 10 + digit。关键是压入前先做溢出判断,不能事后检查。
溢出判断
令 INT_MAX=2147483647,INT_MIN=-2147483648:
- rev > INT_MAX/10 时下一步必溢出;
- rev == INT_MAX/10 且 digit > 7 时溢出;
- rev < INT_MIN/10 时下一步必下溢;
- rev == INT_MIN/10 且 digit < -8 时下溢。
复杂度分析
时间复杂度:O(log10(|x|))。
空间复杂度:O(1)。
常见陷阱
- 先反转再判溢出。
- 负数取模/整除处理不一致导致错误。
- 把末尾 0 保留(应自动去掉)。
- 用字符串法绕过核心考点。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int digit = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE / 10 ||
(rev == Integer.MAX_VALUE / 10 && digit > 7)) return 0;
if (rev < Integer.MIN_VALUE / 10 ||
(rev == Integer.MIN_VALUE / 10 && digit < -8)) return 0;
rev = rev * 10 + digit;
}
return rev;
}
}func reverse(x int) int {
rev := 0
for x != 0 {
digit := x % 10
x /= 10
if rev > 214748364 || (rev == 214748364 && digit > 7) {
return 0
}
if rev < -214748364 || (rev == -214748364 && digit < -8) {
return 0
}
rev = rev*10 + digit
}
return rev
}class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x != 0) {
int digit = x % 10;
x /= 10;
if (rev > INT_MAX / 10 || (rev == INT_MAX / 10 && digit > 7)) return 0;
if (rev < INT_MIN / 10 || (rev == INT_MIN / 10 && digit < -8)) return 0;
rev = rev * 10 + digit;
}
return rev;
}
};class Solution:
def reverse(self, x: int) -> int:
INT_MAX = 2**31 - 1
INT_MIN = -2**31
rev = 0
while x != 0:
digit = int(x % 10) if x > 0 else -int((-x) % 10)
x = int(x / 10)
if rev > INT_MAX // 10 or (rev == INT_MAX // 10 and digit > 7):
return 0
if rev < INT_MIN // 10 or (rev == INT_MIN // 10 and digit < -8):
return 0
rev = rev * 10 + digit
return revvar reverse = function(x) {
const INT_MAX = 2147483647;
const INT_MIN = -2147483648;
let rev = 0;
while (x !== 0) {
const digit = x % 10;
x = (x / 10) | 0;
if (rev > 214748364 || (rev === 214748364 && digit > 7)) return 0;
if (rev < -214748364 || (rev === -214748364 && digit < -8)) return 0;
rev = rev * 10 + digit;
}
return rev;
};
Comments