给出一个 int 型数据,将其各数位对换,符号保持不变
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
虽然是一道简单的问题,但是需要注意一个问题,即数据反转之后的越界问题。对于这个问题,本文提供2个思路。
对越界说明:Java 中 int 数据(有符号32位)的范围为 -(2^31) ~ (2^31)-1,大约为 -2147483648~2147483647 ;而对于 long 型数据(有符号64位),其范围是 -(2^63) ~ (2^63)-1,大约为 -9223372036854775808 ~ 9223372036854775807
1. 转为 String 类型
我们将转换后的结果存放在 long 类型的数据结构中,判断其是否越界,从而返回相应的 int 值。
代码如下:
public int reverse_1(int x) { //47ms
String s = String.valueOf(x);
StringBuffer sb = new StringBuffer(s);
long result = 0;
if(sb.charAt(0) == '-') {
sb.deleteCharAt(0);
sb.reverse();
sb.insert(0, '-');
s = sb.toString();
result = Long.parseLong(s);
} else {
sb.reverse();
s = sb.toString();
result = Long.parseLong(s);
}
if(result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE) {
return (int) result;
} else {
return 0;
}
}
该方法由于需要创建 String、StringBuffer 对象、需要在 int 与 String 对象之间进行转换并且需要对其进行 reverse 操作,故而程序运行时间会比较长,leetcode上的测试时间为 47 ms。
2. 直接对数据进行操作
提供2种方法:第一种是在完成结果之后对结果进行越界的判断;第二种是在生成结果的过程中进行越界判断。
2.1 在完成结果之后再对结果进行越界的判断
仍然将结果存放在 long 型的数据结构中
代码如下:
public int reverse_2(int x) { //37ms
long result = 0;
while(x != 0) {
long tail = x % 10;
result = result * 10 + tail;
x = x / 10;
}
if(result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE) {
return (int) result;
} else {
return 0;
}
}
2.2 在结果生成的过程中就对结果进行越界的判断
对越界判断说明:我们将数据看成为 32 位的二进制,如果程序在执行了 int newResult = result * 10 + tail 之后 newResult 越界了,那么说明其二进制中最左边的那位二进制数由 1 变为 0,那么此时 (newResult - tail) / 10 就不会等于 result ,故如果 if 的条件满足,就说明结果越界;反之,如果 newResult 能够变回 result,那么就说明 newResult 没有越界,那么程序继续执行。
public int reverse_3(int x) { // 30ms
int result = 0;
while (x != 0)
{
int tail = x % 10;
int newResult = result * 10 + tail;
if ((newResult - tail) / 10 != result)
{ return 0; }
result = newResult;
x = x / 10;
}
return result;
}