题目描述
整数反转
给你一个 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代码
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,则不需要去0boolean deleteZero = s.charAt(s.length() - 1) == 48;for (int i = s.length() - 1; i > -1; i--) {// 如果需要删除0并且遇到了非0,则后面就不再去掉0if (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,整数的话不超过2147483647if ((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。
要在没有辅助栈或数组的帮助下「弹出」和「推入」数字,我们可以使用如下数学方法:
// 弹出 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代码:
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;}
}