给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1]
,就返回 0。
示例 1:
输入:x = 123 输出:321
示例 2:
输入:x = -123 输出:-321
示例 3:
输入:x = 120 输出:21
示例 4:
输入:x = 0 输出:0
提示:
-231 <= x <= 231 - 1
题解
简单题,最直接的思路就是翻转了,但是还有个符号位,所以符号位的逻辑要额外处理下。刷题刷得可嗨了……被同事看到了,然后他也想试试,emm过了半天跑来问我这题。顺手写下再给他讲下。
/**
* 字符串拼接转换,性能较低
* 解答成功:
* 执行耗时:3 ms,击败了16.46% 的Java用户
* 内存消耗:35.7 MB,击败了19.93% 的Java用户
* @param x
* @return
*/
public int reverse(int x) {
String str = Integer.toString(x);
char[] arr = str.toCharArray();
int left = 0;
int right = arr.length-1;
if (arr[0]=='-'){
left=1;
}
char tmp;
while (left<right){
tmp = arr[left];
arr[left]=arr[right];
arr[right]=tmp;
left++;
right--;
}
String newStr = new String(arr);
int newInt;
try {
newInt = Integer.parseInt(newStr);
}catch (NumberFormatException e){
//用了异常来实现逻辑、这种方法在实际编码中绝对绝对不可取
return 0;
}
return newInt;
}
但是这边用了个try/catch来处理异常来实现逻辑上的处理,这种处理办法应该是绝对禁止的,非常不符合代码规范。而且try/catch带来的性能损失应该也是不小的。
所以,更好的办法如下:
/**
* 数学计算绝对不溢出方法
* 解答成功:
* 执行耗时:1 ms,击败了100.00% 的Java用户
* 内存消耗:35.6 MB,击败了39.89% 的Java用户
*
* @param x
* @return
*/
public int reverse2(int x) {
String str = Integer.toString(x);
char[] arr = str.toCharArray();
x = 1;
int limit = 0;
if (arr[0]=='-'){
x = -1;
limit = 1;
arr[0] = '0';
}
int num = 0;
for (int i = str.length()-1; i >= limit; i--) {
num = num*10 + (arr[i]-'0');
if (i==limit+1){
if (Integer.MAX_VALUE/10 <num || (Integer.MAX_VALUE/10 == num*10 && Integer.MAX_VALUE%10 < (arr[limit]-'0'))){
return 0;
}
}
}
return x*num;
}
这边溢出判断用了Integer.MAX_VALUE/10来处理,这样能有效避免溢出的问题。另外也有想过溢出后正负数相乘应该为负数这种方法来判断,但是实际数据表明……..乘以10之后溢出的话,仍然可能还为正数,指多绕了几圈又绕回正数区间了,然后再相乘的话是一个更加更加大的数值,依然可能为正数,所以这种判断方式不可取。必须老老实实用Integer.MAX_VALUE/10和还没乘以10进位的数字大小做比较。
顺便,评论区有个这么一个答题内容
public int reverse(int x) {
long n = 0;
while(x != 0) {
n = n*10 + x%10;
x = x/10;
}
return (int)n==n? (int)n:0;
}
一眼看到好惊艳,但是再看下其实不对劲。关键在这里
long n = 0;
long类型变量的存在就忽略了题中要求的“假设环境不允许存储 64 位整数(有符号或无符号)。”
发表评论