整数反转
在 LeetCode 上查看 ↗语音讲解
开车或通勤时可听,跟着思路走一遍
速度
题目描述
给你一个 32 位的有符号整数 x,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位有符号整数的范围 [−2³¹, 2³¹−1],就返回 0。假设环境不允许存储 64 位整数。
示例 1
输入:x = 123
输出:321
示例 2
输入:x = -123
输出:-321
示例 3
输入:x = 120
输出:21
模拟答题者思考
1. 反转数字就是不断「弹出 x 的最低位、推到结果 rev 的最低位」。
2. 难点是 32 位溢出:不能先算完再判断,因为中间就可能溢出。
3. 在 rev = rev*10 + digit 之前先判断:若 rev 已经超过 INT_MAX/10,或等于且下一位过大,就必然溢出,返回 0。
4. Python 没有溢出,但仍按题意在结果超出 32 位范围时返回 0。
变量语义(先读这三句再编码)
| 变量 | 类型 | 语义(三句法) |
|---|---|---|
rev | int | 定义:已经反转好的部分 维护:每弹出 x 的一位就接到 rev 末尾 更新:rev = rev * 10 + digit |
digit | int | 定义:x 当前的最低位 维护:每轮取 x % 10 更新:取完后 x //= 10 |
落码步骤
1. 取符号,转成绝对值处理(Python);C++ 用带符号取模
2. 循环:digit = x % 10,x //= 10
3. 更新前先做溢出判断,安全后 rev = rev*10 + digit
4. 返回 rev(越界返回 0)
代码实现
class Solution:
def reverse(self, x: int) -> int:
INT_MIN, INT_MAX = -2**31, 2**31 - 1
sign = -1 if x < 0 else 1
x = abs(x)
rev = 0
while x:
rev = rev * 10 + x % 10
x //= 10
rev *= sign
return rev if INT_MIN <= rev <= INT_MAX else 0
class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x != 0) {
int digit = x % 10; // C++ 对负数取模结果为负,符号自然保留
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;
}
};
// 时间 O(log|x|),空间 O(1)
复杂度分析
时间复杂度
O(log|x|)
空间复杂度
O(1)
常见坑
溢出判断必须在 rev*10+digit 之前,否则中间结果已经溢出(题设不许用 64 位)。
INT_MAX 末位是 7、INT_MIN 末位是 8,边界时要单独比较最后一位。
末尾有 0 会自然消失(120 → 21),无需特殊处理。
必测边界 Case
Case 1:反转后溢出
x = 1534236469 → 0(超过 INT_MAX)
Case 2:末尾为 0
x = 120 → 21