1. 题目描述
2. 解题思路
简单直接,第一反应想到的便是把整型数据转换为字符数组,使用for循环把该数组倒置后再转换为整形数据,判断其是否溢出,倒置简单,但是怎么判断该数是否溢出呢?可以把该数与最大整型数进行比较,但是,若转换时数据溢出会直接报异常,就无法通过条件语句返回0,于是乎,灵机一动想到了一个逐位比较的方法,在转换前的字符数组从高位开始对每个位的数值进行比较,便可以在不报异常的情况下检测出溢出并实现返回0(该思路理解上存在一定困难,不推荐)
由于上述方法有点绕,不太好理解,可读性不够好,因此便寻找更好的方法,注意到在进行字符到整型转换时,若数据溢出则会报异常,换言之,我们可以使用try-catch
进行异常处理,便可在溢出报异常的情况下成功返回0
当我以为利用捕获异常处理的方法已经天衣无缝的时候,结果发现运行速度却不尽人意,仅打败33%的人,算了,无耻地去看看大婶们的解题思路(噢不,大神们!),于是乎借鉴到了一种仅利用整数运算的全新方法,不仅可读性好,运算速度还贼快,值得推荐
3. 代码实现
3.1 字符串(利用逻辑)
public int reverse(long x) {
int flag = 1;
if (x < 0) {
flag = -1;
}
String s = String.valueOf(Math.abs(x));
char[] chars = s.toCharArray();
int length = chars.length;
char[] nchar = new char[length];
String max = String.valueOf((long) Math.pow(2, 31) - 1);
char[] charsMax = max.toCharArray();
int judge = 0;
if (length == max.length()) {
for (int j = length - 1; j >= 0; j--) {
if(chars[j] <= charsMax[length - j - 1]){
if(chars[j] < charsMax[length - j - 1])
judge = 1;
}
else if(judge == 0) {
return 0;
}
nchar[length - j - 1] = chars[j];
}
}
else {
for (int i = 0; i < length; i++) {
nchar[length - i - 1] = chars[i];
}
}
String s1 = new String(nchar);
return Integer.valueOf(s1) * flag;
}
3.2 字符串(利用异常)
public int reverse(long x) {
int flag = 1;
if (x < 0)
flag = -1;
String s = String.valueOf(Math.abs(x));
char[] chars = s.toCharArray();
int length = chars.length;
char[] nchar = new char[length];
for (int i = 0; i < length; i++) {
nchar[length - i - 1] = chars[i];
}
String s1 = new String(nchar);
int r;
try {
r = Integer.valueOf(s1) * flag;
}catch (Exception e){
return 0;
}
return r;
}
3.3 不使用字符串
public int reverse(int x) {
if (x == 0)
return 0;
int ans = 0;
while (x != 0) {
int i = x % 10; //1.这条语句放if后会多占用300k内存
if (ans * 10 / 10 != ans)
return 0;
ans = ans * 10 + i; //2.直接用x%10代替i也会多占用300k内存
x = x / 10;
}
return ans;
}
注意注意注意,代码上的备注!这是一个很神奇的发现,鄙人暂时还没明白其中的奥妙,有门儿清的大佬们欢迎到评论区留下你们的高见!
ps:很神奇的是验证完上述改动后改回原代码后内存消耗居然还小了100k(迷惑.jpg)
3.4 对比
显然使用纯整数运算的算法更为高效,其直接原因应该是节省了整数与字符串、字符数组之间的相互转换时间