7
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
自解
int reverse(int x){
if(x >-10 && x < 10)
{
return x;
}
double result = 0;
while(x != 0)
{
result = result * 10 + x%10;
x = x/10;
if((result >= 1000000000 || result <= -1000000000) && x > 0)
{
return 0;
}
if(result < -2147483648 || result > 2147483647)
{
return 0;
}
}
return result;
}
官方解
int reverse(int x) {
int rev = 0;
while (x != 0) {
if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {
return 0;
}
int digit = x % 10;
x /= 10;
rev = rev * 10 + digit;
}
return rev;
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/reverse-integer/solution/zheng-shu-fan-zhuan-by-leetcode-solution-bccn/
来源:力扣(LeetCode)
总结
如果这个题目只是涉及到了一个数的翻转,那么确实没什么难的,重点在于这个题目涉及到了原来从来没有注意过的一个东西:溢出。以前从来没有注意过,以至于这一次手忙脚乱,完全不知道该怎么做。说简单点,当一个int型的数足够大,那么当他翻转的时候,他可能会超过整形数据,这个时候就要加以考虑了。而且本题中,说不能使用64位存储,这更是绝杀。我的自解中就使用到了double型数据,我只能说偷懒钻空子都这么拙劣,那也应该要使用long型啊,而且判断方法傻的不行。
自解就不说了,说说官方解的思路,其判断溢出的方法,就是判断每一次加一位之前,其是否存在溢出的可能,将是否溢出的问题转换成了加位之前的数据和整形数据边界值的大小关系问题,得出的结论是(rev < INT_MIN / 10 || rev > INT_MAX / 10),那么加位就不会溢出。
后来一想,确实是这么回事,要是能达到溢出的条件,那么x一定是2^31量级的数,其最高位一定是1或者2,加到最后而要保证这一次的数加位不溢出,那么此时的数应该是2^30量级的,且最高位也是1或者2,最低位要是4或者以下(2^31-1=2147483647,除以10,就是214748364),这个时候再把x加到最低位,其肯定是小于2147483647的,所以就能直接比较加位之前的数据和整形数据边界值的大小得出时候越界,巧妙啊!
其中涉及到的负数取余的问题,参考了该博主的文章:负数取余问题_algsup的博客-CSDN博客_负数取余
做这个题目有个点还是挺欣慰的,第二次见到char** 传参的时候没有懵逼,这就是一个二级指针,指向一个char*的地址,char*用来存放一个字符串的首地址。