声明:这只是一个题解,题目是LeetCode来的。著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目:
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
题解:
解法1:按每一位进行反转,同时检查溢出
分析:
基本的反转公式 : result = result * 10 + pop(下一位数),result 初始值为0,pop = x % 10,x = x/10;
难的地方在于我们需要检查溢出,在上面这个公式里,什么时候会导致溢出?当result * 10 + pop > Integer.MAX_VALUE时会发生溢出。
(1)如果 result 已经大于Integer.MAX_VALUE/10,那后面+pop一定会溢出 ;
(2)如果result = Integer.MAX_VALUE/10,当pop>7的时候会溢出;
没看懂没关系,我来解释一下:
Integer.MAX_VALUE = = 2147483647
当你的result * 10 > Integer.MAX_VALUE,也就是 result > Integer.MAX_VALUE / 10的时候,我假设为214748365,如果让你继续计算,那你新的result = 214748365 * 10 + pop = 214748365(pop),已经溢出了,所以(1)说当你大于的时候,不管pop是多少,一定会溢出。
当你的result = Integer.MAX_VALUE / 10的时候,也就是 result = 214748364,如果你继续计算 result * 10 = 2147483640 + pop,那么pop就不能大于7,否则还是会溢出。
对于负数,也是同理。
所以我们的代码是这样的:
public int reverse(int x) {
int result = 0;
while(x != 0){
int pop = x % 10;
x /= 10;
if(result > Integer.MAX_VALUE/10 || (result == Integer.MAX_VALUE/10 && pop > 7))return 0;
if(result < Integer.MIN_VALUE/10 || (result == Integer.MIN_VALUE/10 && pop < -8))return 0;
result = result * 10 + pop;
}
return result;
}
解法2:偷懒不验证溢出法
既然你在int类型会溢出,而且你的范围也是在[]之内,那我用long类型来做,做完以后和边界对比一下,超过了说明溢出了,就直接返回0。
这种方法实际上在不严格要求不能使用别的类型的时候是比较方便的,因为有时候讨论溢出的条件还是容易出错的。
代码如下:
public int reverse(int x) {
long result = 0;
while(x!=0){
result = result*10 + x%10;
x /= 10;
}
if(result>Integer.MAX_VALUE||result<Integer.MIN_VALUE){
result = 0;
}
return (int)result;
}