多解法详解与边界处理——力扣7.整数反转
【LeetCode 热题】整数反转 —— 多解法详解与边界处理
一、题目描述
给定一个 32 位有符号整数 x
,将其数字部分进行反转,并返回反转后的整数。
如果反转后超出了 32 位有符号整数的范围 [−2^31, 2^31 − 1]
,则返回 0。
注意: 环境不允许存储 64 位整数。
示例
- 输入:
123
→ 输出:321
- 输入:
-123
→ 输出:-321
- 输入:
120
→ 输出:21
- 输入:
0
→ 输出:0
二、思路分析
1. 数字逐位反转(核心解法)
-
利用数学运算:不断对
x % 10
取余得到末尾数字,逐位拼接到结果res
中; -
每次拼接时,先检查是否会溢出 32 位整数范围:
- 正数溢出条件:
res > Integer.MAX_VALUE / 10
或res == Integer.MAX_VALUE / 10 && digit > 7
- 负数溢出条件:
res < Integer.MIN_VALUE / 10
或res == Integer.MIN_VALUE / 10 && digit < -8
- 正数溢出条件:
-
若即将溢出,直接返回 0。
这是官方推荐的 O(log n) 解法。
2. 字符串反转法(不推荐但直观)
- 将整数转为字符串;
- 处理负号,反转数字部分;
- 转回整数时检查是否溢出。
虽然简单,但需要额外空间,性能不如逐位反转。
三、代码实现
方法一:逐位反转(推荐)
class Solution {public int reverse(int x) {int res = 0;while (x != 0) {int digit = x % 10;x /= 10;// 检查是否溢出if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && digit > 7)) {return 0;}if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && digit < -8)) {return 0;}res = res * 10 + digit;}return res;}
}
方法二:字符串反转法
class Solution {public int reverse(int x) {String s = Integer.toString(x);boolean negative = s.charAt(0) == '-';String numStr = negative ? s.substring(1) : s;StringBuilder sb = new StringBuilder(numStr);sb.reverse();String reversed = negative ? "-" + sb.toString() : sb.toString();try {return Integer.parseInt(reversed);} catch (NumberFormatException e) {return 0; // 溢出时返回 0}}
}
四、复杂度分析
-
方法一(逐位反转)
- 时间复杂度:O(log |x|),取决于整数位数。
- 空间复杂度:O(1)。
-
方法二(字符串反转)
- 时间复杂度:O(n),n 为数字位数。
- 空间复杂度:O(n),需要额外字符串存储。
五、总结
- 本题的关键点在于 溢出判断,尤其是
res * 10 + digit
之前的检测。 - 逐位反转法 是首选,性能最佳;
- 字符串法 适合理解,但不满足常数额外空间的要求。
在面试中,建议优先写出 逐位反转法,并清晰解释溢出条件。