一.问题描述
给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [(−2)^31, 2^31 − 1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
二.问题思路
首先,我们得考虑怎么反转数字。比如,123反转成321。负数的话,比如-123变成-321。还有像120变成21,后面的0要去掉。那怎么处理这些情况呢?
反转的话,可以每次取x的最后一位,然后加到结果里。比如,原来的结果乘以10再加上最后一位。但是这里有个问题,如何处理溢出情况?
具体来说,比如,假设结果是res。在每一步,res = res * 10 + pop。取x的最后一位pop,可以用x%10来得到。因为对于负数来说,取余的结果符号和x相同。不管x是正还是负,每一步取余得到的pop的符号和x相同。这样在处理的时候,res的符号也会逐步累积正确的结果。比如,原数是-123,那么每次得到的pop是-3,-2,-1。然后res = 0*10 + (-3) → -3。然后-3*10 + (-2) → -32。然后-32*10 + (-1) → -321。比如-123%10是-3。但是在乘以10之前,得判断res是否已经超过了INT_MAX /10,或者等于INT_MAX/10的时候,pop是否超过余下的部分。比如,对于正数来说,INT_MAX是2147483647。所以如果当前的res已经大于214748364,或者等于214748364且pop>7的话,那么乘以10再加上pop就会溢出。这时候就要返回0。同样对于负数的情况,INT_MIN是-2147483648。如果res是负数,那么当res < -214748364,或者等于-214748364且pop < -8的话,就会溢出。
代码实现
#include <climits>
class Solution {
public:
int reverse(int x) {
int res = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
// 检查正溢出
if (res > INT_MAX / 10 || (res == INT_MAX / 10 && pop > 7)) {
return 0;
}
// 检查负溢出
if (res < INT_MIN / 10 || (res == INT_MIN / 10 && pop < -8)) {
return 0;
}
res = res * 10 + pop;
}
return res;
}
};