整数处理时注意大数的溢出

7.题目链接-来源:力扣(LeetCode)(简单)

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [-$2^31$,  $2^31$ − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。
 
示例 1:

输入:x = 123
输出:321

####思路:
大体思路就是对 x 取余加到结果数 ret 当中,ret 左移,x右移,循环迭代即可。
难点在于细节,不能存储64位数据的情况下如何识别32位数据的溢出。
首先确定输入范围,x本身不会溢出,那么最大位数就是十进制10位,[-$2^31$,  $2^31$ − 1],即[-2147483648, 2147483647]。
考虑一个反转后的部分结果 ret,当 ret 达到9位的,并且 x 还不为0的时候,我们就可以考虑溢出问题了。

  • 对于 ret > 214748364 或者 ret < -214748364 的情况,继续右移之后必然溢出,不用考虑x。
  • 对于 -214748364 < ret < 214748364,继续右移后必然不溢出,不用考虑x。
  • 对于 ret = -214748364 或 ret = 214748364,x < -8 或者 x > 7 会溢出,而其他情况不会溢出。
    将这些情况考虑清楚即可,注意循环继续的条件是 x != 0。
    时间复杂度:O(n) n为x的位数
    空间复杂度:O(1)

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int reverse(int x) {
int ret = 0;
while (x != 0) {
if ((x < 10 && x >= 0) || (x > -10 && x < 0)) {
if (ret > Integer.MAX_VALUE / 10 || ret < Integer.MIN_VALUE / 10) {
return 0;
} else if (((ret == Integer.MAX_VALUE / 10) && x > 7) || ((ret == Integer.MIN_VALUE / 10) && x < -8)) {
return 0;
}
}
ret *= 10;
ret += x % 10;
x /= 10;
}
return ret;
}
}