整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
解题思路如下:
我们想重复“弹出” x 的最后一位数字,并将它“推入”到 rev 的后面。最后, rev 将与 x 相反
// 弹出最后一位
pop = x % 10; // 在x为负时,pop也为负
x /= 10;
// 推入到rev中的后面
temp = rev * 10 + pop;
rev = temp;
当 temp=rev*10+pop时会导致溢出, 这里我们分两种情况来讨论, 在C中, [−2^31, 2^31 −1]= [INT_MIN,INT_MAX]
首先我们假设 rev和 pop 是正数:
如果 temp=rev×10+pop导致溢出, 也就是temp=rev×10+pop > INT_MAX,
==> rev×10 > INT_MAX - pop
==> revrevrev >( INT_MAX−pop)/10 时会导致溢出, 因为pop的范围是[0,9], 要使 INTMAX-pop 取极限MAX值, 则 pop = 0, 以下分情形讨论:
如果 rev > INTMAX/10时肯定会导致溢出。
如果 rev = INTMAX/10时,因为INT_MAX = 2147483647,所以rev = 214748364, 所以当 pop > 7,肯定会导致溢出。
我们再假设 rev 和 pop 是负数:
如果 temp=rev×10+pop导致溢出,也就是temp=rev×10+pop < INT_MIN,
==> rev×10 < INT_MIN - pop
==>revrevrev <( INT_MIN−pop)/10 时会导致溢出,, 因为pop的范围是[-9,0], 要使 INTMIN-pop 取极限MIN值, 则 pop = 0, 以下分情形讨论:
如果 rev< INT_MIN/10 时肯定会导致溢出。
如果 rev = INT_MIN/10 时,因为INT_MIN = -2147483648,所以revrevrev = -214748364, 所以当 pop< -8,肯定会导致溢出。
进一步深入讨论,因为 INT_MAX = 2147483647, INT_MIN = -2147483648,10位数,要超出范围,我们的rev要有9位,也就是我们的原数 x 要有10位,所以这时我们的 pop 为 x的最前面一个数字,因为 x 的范围是[INT_MIN,INT_MAX],意味着此时10位的 x 最前面一个数字最大只能为2,也就是 pop只能为 1、2 或 -1, -2, 所以前面的情形2可以排除。
代码实现如下:
#define INT_MIN -2147483648
#define INT_MAX 2147483647
int reverse(int x){
int rev = 0;
while(x != 0){
int pop = x % 10;
x = x / 10;
if(rev > INT_MAX / 10 || (rev == INT_MAX / 10 && pop >7)){
rev = 0;
break;
}else if(rev < INT_MIN / 10 || (rev == INT_MIN / 10 && x < -8)){
rev = 0;
break;
}
rev = rev * 10 + pop;
}
return rev;
}
主要需要关注的就是溢出的问题。
作者:bian-bian-xiong
链接:https://leetcode-cn.com/problems/reverse-integer/solution/7zheng-shu-fan-zhuan-cc-by-bian-bian-xiong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。