题目描述:
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
题目解答:
方法1:
该题主要是溢出情况的判断。运行时间12ms,代码如下。
另外想了一下溢出时的溢出结果,如果a + b
发生了溢出,首先进行二进制相加,如果没有超过32位,则结果就是对应二进制的数字,高位为0时结果为正数,高位为1时为负数;如果超过32位,则只取后32位,结果就是这32位形成的数字。相减时,实际也是两个数字相加,只不过负数的最高位为1。
int reverse(int x) {
if(x == INT_MAX || x == INT_MIN || x == 0)
return 0;
int result = 0, tempMax = INT_MAX / 10;
bool flag = false;
if(x < 0) {
flag = true;
x = -x;
}
int t = x % 10;
while(x) {
if(result > tempMax)
return 0;
if(result == tempMax && ((!flag && t > 7) || (t > 8 && flag)))
return 0;
if(t == 8 && result == tempMax && flag)
return INT_MIN;
result = result * 10 + t;
x = x / 10;
t = x % 10;
}
return (flag ? -result : result);
}
不过在讨论区看到一种更加巧妙的方法来处理溢出情况,运算之后再往回复原,如果不等于原来数字,则判断出发生了溢出。代码如下。
int reverse(int x) {
if(x == INT_MAX || x == INT_MIN || x == 0)
return 0;
int result = 0, new_result = 0;
int t = x % 10;
while(x) {
new_result = result * 10 + t;
if((new_result - t) / 10 != result)
return 0;
result = result * 10 + t;
x = x / 10;
t = x % 10;
}
return result;
}
然后自己又想了想,发现有更清晰的方式,如果result
的绝对值大于tMax
,必定返回0,如果result == tMax
,溢出时t
为8或者9,但这样的话原本输入的就不合法了,超过int自身的范围了,所以直接判断result
的绝对值与tmax
的关系即可。
int reverse(int x) {
if(x == INT_MAX || x == INT_MIN || x == 0)
return 0;
int result = 0, new_result = 0;
int t = x % 10;
int tMax = INT_MAX / 10;
while(x) {
if(abs(result) > tMax)
return 0;
result = result * 10 + t;
x = x / 10;
t = x % 10;
}
return result;
}