运行结果
执行结果:通过
执行用时 :2 ms, 在所有 java 提交中击败了53.22%的用户
内存消耗 :33.5 MB, 在所有 java 提交中击败了80.84%的用户
代码和注释
class Solution {
public int reverse(int x) {
int tmp = x;
int revs = 0;
// 循环条件:没有遍历到最高位
while ((tmp / 10 != 0) || (tmp % 10 != 0))
{
if (x > 0)
{
// 判断次高位是否溢出
if (revs > ((1 << 30) - 1 + (1 << 30)) / 10) return 0;
// 判断最低位是否溢出
if ((revs == (((1 << 30) - 1 + (1 << 30)) / 10)) && (tmp % 10 > 7)) return 0;
}
if (x < 0)
{
// 判断次高位是否溢出
if (revs < -((1 << 30) - 1 + (1 << 30)) / 10) return 0;
// 判断最低位是否溢出
if ((revs == (((1 << 30) - 1 + (1 << 30)) / 10)) && (tmp % 10 < -8)) return 0;
}
// 反转累加
revs = revs * 10 + tmp % 10;
// 移位
tmp /= 10;
}
return revs;
}
}
做题体会
1.实现基本思路是:通过不断取数反转累加,即:revs = revs * 10 + tmp % 10。
2.32位有符号数范围不同: [−2e31,2e31 − 1],需要分x>0和x<0的情况讨论。
3.循环退出条件是,处理完原数最高位后,tmp为零退出循环。
4.判断溢出的思路是:当累加数revs的绝对值大于32位有符号数最大范围除以10,revs的下次乘10操作,必然溢出;如果小于,必然不会溢出;如果等于,则需要讨论反转后个位是否会超限,正数不能超过7,负数不能小于-8。
5.操作1<<31,会直接溢出,因为整数的范围是1<<31-1,所以需要(1 << 30) - 1 + (1 << 30)。
6.如果x为0,直接返回0。
7.时间复杂度:O(log10 x)
官方解答
class Solution {
public int reverse(int x) {
int tmp = x;
int revs = 0;
// 循环条件:没有遍历到最高位
while (tmp != 0)
{
// 判断是否溢出
if (revs > Integer.MAX_VALUE / 10 || (revs == Integer.MAX_VALUE / 10 && tmp % 10 > 7)) return 0;
if (revs < Integer.MIN_VALUE / 10 || (revs == Integer.MIN_VALUE / 10 && tmp % 10 < -8)) return 0;
// 反转累加
revs = revs * 10 + tmp % 10;
tmp /= 10;
}
return revs;
}
}
运行结果
执行结果:通过
执行用时 :1 ms, 在所有 java 提交中击败了100.00%的用户
内存消耗 :33.6 MB, 在所有 java 提交中击败了79.94%的用户
差别
1.循环判断条件简化,本质上就是tmp != 0才循环
2.整形数的最大范围不是通过移位计算得到,而是直接取用:Integer.MAX_VALUE和Integer.MIN_VALUE。
3.没有判断x的正负,因为正负数的溢出条件互斥,可以用并列的两个if分别判断。
4.大于最大范围除10,等于最大范围数除10且个位溢出,两者满足其一均溢出,可用“或”:|| 整合。