原题链接 https://leetcode.cn/problems/reverse-integer/
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
分析:
1 .如果不考虑反转过程中的数值溢出,利用 mod = x%10, x = x/10; y=y*10+mod
模仿栈
的效果,可以容易的写出代码,如下:
public int reverse(int x) {
boolean positive = x >= 0;
x = positive ? x : -x;
int y = 0;
while (x != 0) {
int mod = x % 10;
x = x / 10;
y = y * 10 + mod;
}
return positive ? y : -y;
}
2 . 但是由于要应对可能数据溢出的场景,上述代码需要进行稍微修改。举例说明,当x=1534236469
时,如果反转,值为9646324351
,超过了Integer的最大值2147483647
。
假设x是正数,进一步分析,可以发现,只有当x是十位十进制数时,且在处理x的最高数值位这一步时,才可能发生溢出,即在最后一次执行 y = y * 10 + mod
时可能发生溢出。
我们需要提前一步进行判断,
如果y>(Integer.MAX_VALUE/10)=214748364
,则y最小为214748365
,y*10
后就会溢出。
如果y==(Integer.MAX_VALUE/10)=214748364
, 则y*10+mod
后不会溢出,因为mod最大为2
综上分析,当x>=0时,若 y>(Integer.MAX_VALUE/10)
,就会溢出。
同理,可以分析得到, x<0时,若y<(Integer.MIN_VALUE/10)
,就会溢出。
因此上述代码可以更改为
public int reverse(int x) {
boolean positive = x >= 0;
x = positive ? x : -x;
int y = 0;
while (x != 0) {
if (positive && y > Integer.MAX_VALUE/10){
return 0;
}
if (!positive && y < Integer.MIN_VALUE/10){
return 0;
}
int mod = x % 10;
x = x / 10;
y = y * 10 + mod;
}
return positive ? y : -y;
}
3 . 再进一步分析,是否有必要将x是正负数显示区分出来。答案是没必要,不论x是正数还是负数,mod = x%10, x=x/10, y= y*10+mod
的逻辑都不会变。只是在判断是否可能溢出的地方需要判断下,上述代码可简化为
public int reverse(int x) {
int y = 0;
while (x != 0) {
if (y > Integer.MAX_VALUE/10 || y < Integer.MIN_VALUE/10){
return 0;
}
int mod = x % 10;
x = x / 10;
y = y * 10 + mod;
}
return y;
}