题目:将一个32位的有符号整数x的数字部分进行反转,输出反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。要求不允许存储 64 位整数(有符号或无符号)。
eg:
输入:x = 12345
输出:54321
分析:
用循环取模的方法来进行反转,n = n*10 + x%10 , x = x/10 ; (n为反转后得到的数字)
进行反转不难,本题的难点是要判断反转后得到的整数 n 是否超过了有符号整数的范围。
INT_MAX = 2^31-1 = 2,147,483,647
INT_MIN = - 2^31 = -2,147,483,648
1、当 n > INT_MAX/10 时,若还有数字要推入到n的尾部,就一定会超过最大范围;
2、当 n = INT_MAX/10 时:
若还有数字要推入到n的尾部,就表示 x 的位数同INT_MAX一样,都是10位。
因为INT_MAX的最低位是7 ,所以下一步要推入n的尾部的数字如果小于或者等于7,就不会超出最大范围。
又因为 n 是由 int 形的 x 反转而来的,因此 x 本身就不会超出最大范围,INT_MAX的最高位为2,所以 x 的最高位小于或等于2,一定满足小于 7 的条件,所以当 n = INT_MAX/10 时,一定不会超过最大范围。
3、当 n < INT_MAX/10 时, 就算还有数字要推入 n 的尾部,一定有: n*10+x%10 < INT_MAX, 既得到的 n 一定不会大于 INT_MAX 。
综上,可以在每次推入新的数之前进行判断。若 n <= INT_MAX/10 ,则知道推入新数之后不会超出范围;若 n > INT_MAX/10 ,则推入新数后一定超出范围,因此直接返回0。
同理,在每次推入新的数之前进行判断。若 n >= INT_MIN/10 ,则知道推入新数之后不会超出范围;若 n < INT_MIN/10 ,则推入新数后一定超出范围,因此直接返回0。
int reverse(int x) {
int n=0;
while(x){
if(n<INT_MIN/10 || n>INT_MAX /10) return 0; //推入后一定会超出范围,直接返回0
n=n*10+x%10;
x=x/10;
}
return n;
//if(n<INT_MAX && n>INT_MIN) return n;
//else return 0;
//return (n<INT_MIN||n>INT_MAX)?0:n;
}