题目
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:
-231 <= x <= 231 - 1
利用数组+String进行翻转
先看一下我写的,其中有两个致命的问题
- 用的是字符串+数组,其实这题是不建议用数组的方式
- 用了Double ,题目中明确表示:假设环境不允许存储 64 位整数(有符号或无符号)。
虽然最后也能够提交。但是却已经跑题了,这个只是给大家一个思路,轻喷哈!
class Solution {
public int reverse(int x) {
String s = String.valueOf(x);
//将s分割
char[] chars = s.toCharArray();
if (x>Integer.MAX_VALUE || x<Integer.MIN_VALUE){
return 0;
}
//判断
if (chars.length == 1) {
return turnInt(chars);
} else if (chars[0] == '-') {
char[] jian = jian(chars);
return turnInt(jian);
} else if (chars[chars.length - 1] == '0') {
char[] ifZero = ifZero(chars);
return turnInt(ifZero);
} else {
char[] common = common(chars);
return turnInt(common);
}
}
public static int turnInt(char[] chars) {
String s = String.valueOf(chars);
double v = Double.parseDouble(s);
if (v>Integer.MAX_VALUE || v<Integer.MIN_VALUE){
return 0;
}
return (int)v;
}
public static char[] common(char[] chars) {
char[] chars1 = new char[chars.length];
int j = 0;
for (int i = chars.length - 1; i >= 0; i--) {
chars1[j] = chars[i];
j++;
}
return chars1;
}
public static void out(char[] chars) {
for (char aChar : chars) {
System.out.print(aChar);
}
}
//如果第一个字符是减的话,那么第一个位置的负号不变
public static char[] jian(char[] chars) {
char[] chars1 = new char[chars.length];
chars1[0] = chars[0];
int j = 1;
for (int i = chars.length - 1; i > 0; i--) {
chars1[j] = chars[i];
j++;
}
return chars1;
}
//如果第一个字符是0
public static char[] ifZero(char[] chars) {
char[] chars1 = new char[chars.length - 1];
int j = 0;
for (int i = chars.length - 1; i > 0; i--) {
chars1[j] = chars[i - 1];
j++;
}
return chars1;
}
}
【官方算法】利用数学方法进行翻转
下面我们来看看官方对此题的讲解,发现官方是用的数学方法推导出公式,然后进行处理,性能优化和处理上都得到了很大的提升。
public static int reverse(int x) {
int rev = 0;
while (x != 0) {
if (rev > Integer.MAX_VALUE / 10 || rev < Integer.MIN_VALUE / 10) {
return 0;
}
int dight= x % 10;
x /= 10;
rev = rev * 10 + dight;
}
return rev;
}
这里对式子进行了整理,发现我们只需要考虑 rev 和 (INT_MAX)/10 便可以
- 如果左边括号里的式子大于0,那么 * 10 后,肯定大于右边的式子,所以在最后一次出栈前对比发现已经超过最大值,那么肯定就超了。
- 如果 = ,这里 = 我感觉用的很巧妙,因为 = 说明长度是一样的。然后判断余数。
- 如果小于,我认为的情况下是因为rev已经小于最大值,那么其首位肯定也没最大值大,那么必然是一直小于最大值的。
看了官方的,真的很受启发。估计是我比较菜的原因,哈哈。