整数反转原题地址
方法一:数学
反转整数
如何反转一个整数呢?考虑整数操作的3个技巧:
- xmod10可以取出x的最低位,如x=123,xmod10=3。
- x/=10可以去掉x的最低位,如x=123,x/=10,x=12。
- x=x*10+y可以在x后面续上y,其中y是一位数,如x=123,y=4,x=x*10+y,x=1234。
假设要反转的整数为x,反转后的整数存储在变量rev中,rev一开始初始化为0,那么反复执行以下操作:
- digit=xmod10,取出x的最低位数。
- x/=10,去掉x的最低位数。
- rev=rev*10+digit,在rev后面续上digit。
直到x为0为止,此时rev存储的数据符合题目要求。
判断溢出
问题在于,如何判断插入后的数据是否超出[INT_MIN,INT_MAX]的范围,导致溢出?
我们来探索不等式成立的充分必要条件。
先看右半边,即。
对于任意整数i,我们有,如对于123,123/10=12,123mod10=3,123=12*10+3。
不等式化为:,带入,,,
移项化简得:,记,
- 当rev=m时,如果还要推入数字,那么digit≤2,因为INT_MAX的最高位为2,此时不等式左边等于0,右边为正数,不等式恒成立。
- 当rev>m时,不等式左边至少是10,右边至多是7,不等式恒不成立。
- 当rev<m时,不等式左边至多是-10,右边至少是7-9=-2,不等式恒成立。
所以原不等式右半边成立的充分必要条件是,即。同理左半边成立的充分必要条件是。
原不等式成立的充分必要条件是
// 方法一:数学
class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x)
{
if (rev < INT_MIN / 10 || rev > INT_MAX / 10)
{
return 0;
}
// rev后面续上x的最低位
rev = rev * 10 + x % 10;
// 去掉x的最低位
x /= 10;
}
return rev;
}
};