力扣(07)一道简单题引起的一系列问题
问题描述
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
突发奇想(使用字符串反转解决问题)
public static int reverse(int x) {
boolean flag = false;
//如果数值是负数,转换成整数
if (x < 0) {
x = Math.abs(x);
flag = true;
}
StringBuilder sb = new StringBuilder(x + "");
int result = Integer.parseInt(sb.reverse().toString());
if (result < -Math.pow(2, 31) || result > Math.pow(2, 31) - 1) {
return 0;
}
//将数值还原
if (flag) {
result = -result;
}
return result;
}
简单测试,没问问题。提交
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 776, java.base/java.lang.Integer.parseInt
at line 15, Solution.reverse
at line 54, __DriverSolution__.__helper__
at line 84, __Driver__.main
问题一 数值超过int范围
反转后的字符串转换成int,数值越界。
解决使用Long
public static int reverse(int x) {
boolean flag = false;
//如果数值是负数,转换成整数
if (x < 0) {
x = Math.abs(x);
flag = true;
}
StringBuilder sb = new StringBuilder(x + "");
//使用long
long result = Long.parseLong(sb.reverse().toString());
if (result < -Math.pow(2, 31) || result > Math.pow(2, 31) - 1) {
return 0;
}
//将数值还原
if (flag) {
result = -result;
}
return (int)result;
}
再次提交
java.lang.NumberFormatException: For input string: "8463847412-"
at line 68, java.base/java.lang.NumberFormatException.forInputString
at line 699, java.base/java.lang.Long.parseLong
at line 824, java.base/java.lang.Long.parseLong
at line 11, Solution.reverse
at line 54, __DriverSolution__.__helper__
at line 84, __Driver__.main
问题二 绝对值失效
debug,找失败原因
查阅资料,直观的说,-2147483648绝对值是2147483648
计算机内存储使用补码,在计算机中,10000000 00000000 00000000 00000000 就是-2147483648。
从二进制的角度来看,负数的二进制就是其自身正数的所有位反码加1,所以负数取绝对值就是其二进制减一再取反(或者是取反再加一),10000000 00000000 00000000 00000000 计算过后还是它,所以-2147483648取了绝对值后还是不变。
public static int reverse(int x) {
boolean flag = false;
//如果数值是负数,转换成整数
if (x < 0) {
//对应Integer绝对值的最小值,反转后大于Integer的最大值,越界
x = Math.max(Math.abs(x),0);
flag = true;
}
StringBuilder sb = new StringBuilder(x + "");
//使用long
long result = Long.parseLong(sb.reverse().toString());
if (result < Integer.MIN_VALUE || result > Integer.MAX_VALUE) {
return 0;
}
//将数值还原
if (flag) {
result = -result;
}
return (int)result;
}
提交,通过。
学习解法
public static int reverse(int x) {
long n = 0;
while (x != 0) {
n = n * 10 + x % 10;
x /= 10;
}
return (int) n == n ? (int) n : 0;
}