题目与官方答案
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:输入: -123
输出: -321
示例 3:输入: 120
输出: 21
注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
官方给出的答案确实是挺棒的,逻辑完美,代码简洁。先把官方的代码贴上来吧:
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7))
return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8))
return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
官方的代码建立在非常清晰的数学分析的基础之上:
当(rev = rev * 10 + pop) > Integer.MAX_VALUE的时候,溢出就已经发生了。我们需要在溢出发生前返回0这个值。
Integer.MAX_VALUE = 2147483647:
- rev > (Integer.MAX_VALUE / 10),肯定会造成overflow;
- rev == (Integer.MAX_VALUE / 10),则当pop > 7的时候才会造成overflow;
用同样的逻辑来分析当rev < Integer.MIN_VALUE的情况就可以了。
这个问题的一个关键点是,要在溢出发生之前就终止程序,而不是在溢出之后,再来判断rev是否会导致溢出。
有很多网友在代码中用到了long这个数据类型。
public class Solution {
public int reverse(int x) {
long res = 0;
for (; x != 0; x /= 10)
res = res * 10 + x % 10;
return res > Integer.MAX_VALUE || res < Integer.MIN_VALUE ? 0 : (int) res;
}
}
关于Integer.MAX_VALUE和Integer.MIN_VALUE
Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE。这是Math.abs()的一种特殊情况。
当我们给一个int类型的变量,赋予一个超过Integer.MAX_VALUE的值,该变量 == Integer.MIN_VALUE(最小的int负数)。
https://www.geeksforgeeks.org/integer-max_value-and-integer-min_value-in-java-with-examples/