题目描述
给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:
-2^31 <= x <= 2^31 - 1
解法
- 转字符串反转
转为字符串后从后往前遍历反转
java代码
java
public int revers(int x) {
String s = String.valueOf(x);
// 如果第一个是-,则删除,标记有横杠
boolean hasHyphen = false;
if (s.charAt(0) == 45) {
s = s.substring(1);
hasHyphen = true;
}
StringBuilder resBuilder = new StringBuilder();
// 注意点:1.末尾的0去掉,中间的0保留;2.如果会死负数,把-去掉;2.-2147483648超过了范围,返回0
// 最后一位是否是0,如果是0,把末尾的0都去掉,遇到第一个非0后,不再去掉0;不是0,则不需要去0
boolean deleteZero = s.charAt(s.length() - 1) == 48;
for (int i = s.length() - 1; i > -1; i--) {
// 如果需要删除0并且遇到了非0,则后面就不再去掉0
if (deleteZero && s.charAt(i) != 48) {
deleteZero = false;
}
// 如果是0并且需要删除0,则略过
if (s.charAt(i) == 48 && deleteZero) {
continue;
}
resBuilder.append(s.charAt(i));
}
String resString = resBuilder.toString();
// 判断是否超过范围:负数的话不超过2147483648,整数的话不超过2147483647
if ((hasHyphen && (resString.length() > 10 || (resString.length() == 10 && resString.compareTo("2147483648") > 0)))
|| (!hasHyphen && (resString.length() > 10 || (resString.length() == 10 && resString.compareTo("2147483647") > 0)))) {
return 0;
}
int res = "".equals(resString) ? 0 : Integer.parseInt(resString);
return hasHyphen ? -res: res;
}
- 官方解法:数学方法
记rev为翻转后的数字,为完成翻转,我们可以重复「弹出」x 的末尾数字,将其「推入」rev 的末尾,直至 x 为 0。
要在没有辅助栈或数组的帮助下「弹出」和「推入」数字,我们可以使用如下数学方法:
java
// 弹出 x 的末尾数字 digit
digit = x % 10
x /= 10
// 将数字 digit 推入 rev 末尾
rev = rev * 10 + digit
题目需要判断反转后的数字是否超过 323232 位有符号整数的范围 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1] [−231,231−1]。例如 x = 2123456789 x=2123456789 x=2123456789反转后的 r e v = 9876543212 > 2 31 − 1 = 2147483647 {rev}=9876543212>2^{31}-1=2147483647 rev=9876543212>231−1=2147483647,超过了 323232 位有符号整数的范围。
因此我们需要在「推入」数字之前,判断是否满足:
− 2 31 ≤ r e v ⋅ 10 + d i g i t ≤ 2 31 − 1 -2^{31}≤rev⋅10+digit≤2^{31}-1 −231≤rev⋅10+digit≤231−1
若该不等式不成立则返回 0。
但是题目要求不允许使用 646464 位整数,即运算过程中的数字必须在 323232 位有符号整数的范围内,因此我们不能直接按照上述式子计算,需要另寻他路。
考虑 x>0的情况,记 I N T _ M A X = 2 31 − 1 = 2147483647 {INT\_MAX}=2^{31}-1=2147483647 INT_MAX=231−1=2147483647,由于
则不等式
r e v ⋅ 10 + d i g i t ≤ I N T M A X rev⋅10+digit≤INT_MAX rev⋅10+digit≤INTMAX
等价于
移项得
讨论该不等式成立的条件:
注意到当相等时若还能推入数字,则说明 x 的位数与 INT_MAX的位数相同,且要推入的数字 digit 为 x 的最高位。由于 x 不超过 INT_MAX,因此 digit 不会超过 INT_MAX 的最高位,即 digit≤2。所以实际上当 相等时不等式必定成立。
因此判定条件可简化为:当且仅当小于等于时,就成立。
x<0 的情况类似。
综上所述,判断不等式
− 2 31 ≤ r e v ⋅ 10 + d i g i t ≤ 2 31 − 1 -2^{31}≤rev⋅10+digit≤2^{31}-1 −231≤rev⋅10+digit≤231−1
是否成立,可改为判断不等式
I N T M I N / 10 < = r e v < = I N T M A X / 10 INT_MIN / 10 <= rev <= INT_MAX / 10 INTMIN/10<=rev<=INTMAX/10
java代码:
java
class Solution {
public int reverse(int x) {
int rev = 0; // 结果数字
while (x != 0) {
if (rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10) {
return 0;
}
// 取余数
int digit = x % 10;
// 原数字除以10后,得到的商为下一位数字
x /= 10;
// 原来的rev*10等于向高位移动一位,再加上余数,就是新数字
rev = rev * 10 + digit;
}
return rev;
}
}