题目
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123 输出:321
示例 2:
输入:x = -123 输出:-321
示例 3:
输入:x = 120 输出:21
示例 4:
输入:x = 0 输出:0
思路
看到这道题目的时候,首先想到的是转换成字符串,然后翻转,所以迅速写完第一版
public int reverse(int x) { StringBuffer s = new StringBuffer(String.valueOf(x)); if(x> 0){ return Integer.valueOf(s.reverse().toString()); }else if(x <0){ return - Integer.valueOf(s.reverse().toString().substring(0,s.length()-1)); }else{ return 0; } }
执行出错信息:
java.lang.NumberFormatException: For input string: "9646324351" at line 68, java.base/java.lang.NumberFormatException.forInputString at line 658, java.base/java.lang.Integer.parseInt at line 989, java.base/java.lang.Integer.valueOf at line 6, Solution.reverse at line 54, __DriverSolution__.__helper__ at line 84, __Driver__.main 最后执行的输入: 1534236469
这个报错是因为当输入是1534236469,翻转后是9646324351
但是这样再用Integer.valurOf()就会超过int类型的最大值2147483647
如果能够看出问题所在,这时按照题目要求,超出范围后直接返回0
我们就可以利用异常来控制返回,当有异常时直接返回0
public static int reverse(int x) { try { StringBuffer s = new StringBuffer(String.valueOf(x)); if (x > 0) { return Integer.valueOf(s.reverse().toString()); } else if (x < 0) { return -Integer.valueOf(s.reverse().toString().substring(0, s.length() - 1)); } else { return 0; } } catch (Exception e) { return 0; } }
执行用时:2 ms, 在所有 Java 提交中击败了22.09%的用户
内存消耗:35.7 MB, 在所有 Java 提交中击败了22.48%的用户
从结果看,效率不算太高,可以考虑下其他方法,字符串操作相对比较耗时
解法二
由于字符串操作比较耗时,所以选择数学公式方式实现
依次取出当前数字的最后一位数,累加。
关键在于如何判断整数溢出:
可以每次操作后的数字用临时变量存储,对该变量反向运算,
若与操作前的结果不等,则发生溢出,直接返回0
public int reverse(int x) { int result = 0; while(x != 0){ //当前操作位数字 int cuur = x%10; //result*10相当于低位每次右移以为就乘以10,比如123, 3*10, 3*10*10*10+2*10,3*10*10+2*10*10 +1*10 int temp = cuur + result*10; //上一行运算的逆运算,判断是否超出int范围 if((temp - cuur)/10 != result){ return 0; } x = x/10; result = temp; } return result; }
执行用时:1 ms, 在所有 Java 提交中击败了97.47%的用户
内存消耗:35.6 MB, 在所有 Java 提交中击败了30.81%的用户
解法三
int类型的数字翻转也不会超过long的范围,所以可以利用long类型和int类型转换后
判断是否相等来验证是否超出int范围
public int reverse(int x) { long result = 0; while(x != 0){ int cuur = x%10; result = result *10 + cuur; x = x/10; } //如果不超出范围,强转类型后数值不变化 int res = (int)result; return res == result? res: 0; }
执行用时:1 ms, 在所有 Java 提交中击败了97.47%的用户
内存消耗:35.2 MB, 在所有 Java 提交中击败了94.37%的用户