题目描述:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
对int类型的简单介绍
int为4个字节:1字节=8位,所以int为32位在计算机中存储的二进制位数。
int -2147483648~2147483647
unsigned int 0~4294967295
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
算法分析:
这题算法很简单,最关键的点是注意事项,如果反转后整数溢出就直接返回0;
这里的溢出是指实时的,只要一溢出就会立刻出错,所以在每一次计算sum的之前都要判断一次会不会溢出。
C语言实现:
int reverse(int x){
int sum=0;
int temp=0;
while(x)
{
temp=x%10;
x=x/10;
if ( sum > 2147483647/10 || (sum == 2147483647 / 10 &&temp> 7)) return 0;
if (sum < -2147483648/10 || (sum == -2147483648/ 10 && temp < -8)) return 0;
sum=sum*10+temp;
}
return sum;
}
计算sum的值必须在两个if语句之前
分析:
sum=sum*10+temp这一语句很容易导致溢出发生,幸运的是,事先检查这个语句是否会导致溢出很容易。
为了便于解释,我们假设 sum是正数。
- 如果
- sum= sum⋅10+pop导致溢出,那么一定有后面的sum≥INTMAX/10。
- 如果 后面的sum>INTMAX/10,那么 sum= sum⋅10+pop一定会溢出。
- 如果 后面的sum==INTMAX/10,那么只要 temp>7, sum= sum⋅10+temp就会溢出。
java语言实现
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
还可以对此算法进行改进:
- 最大的值与最小的值为:[−2^31, 2^31 − 1], 即:[-2147483648, 2147483647]。
- 如果 y * 10 + x % 10溢出,则 y>=214748364 。
- 当y=214748364时,输入的值只能是1463847412,不溢出。
因为在int所可以表示的最大值和最小值中的首数字只能是2或者1。
即:y > 214748364 || y < -214748364 必定溢出
代码如下:
class Solution {
public int reverse(int x) {
int y = 0;
while (x != 0) {
if (y > 214748364 || y < -214748364) {
return 0;
}
y = y * 10 + x % 10;
x = x / 10;
}
return y;
}
}